Zum Inhalt springen

Problem mit filebuf


Kitty82

Empfohlene Beiträge

Hallo Leute,

hoffe, ihr könnt mir weiterhelfen.

Habe folgenden code:


//...
#include "time.h"
#include "fstream"
#include "string"

using namespace std;

void Bla::Func1()
{
ofstream read_out;

//...

read_out.open(path, ios::out, filebuf::sh_none);
read_out << "Text";
read_out.close();
}[/PHP]

Jedoch stimmt bei diesem Code irgendwas nicht. Er bringt mir immer die Fehlermeldungen:

error C2039: 'sh_none' : Ist kein Element von 'basic_filebuf<char,struct std::char_traits<char> >'

error C2065: 'sh_none' : nichtdeklarierter Bezeichner

und zeigt mir die Zeile, worin filebuf::sh_none drin steht. Was hab ich vergessen?

Habe filebuf::sh_none deshalb gewählt, damit wenn die Datei so geöffnet wird, jemand anderes -wenn er diese datei ebenfalls öffnen will- nix ändern kann (schreibgeschützt).

Danke schon im Voraus,

Gruß Kitty

Link zu diesem Kommentar
Auf anderen Seiten teilen

vielen dank für eure schnellen Antworten!

basic_filebuf::open hat nur zwei Parameter. Soweit ich weiß, behandelt der Standard so etwas wie Schreibschutz nicht, da wirst du auf betriebssystemspezifische Funktionen zurückgreifen müssen.

kannst du mir kurz sagen was du mit betriebssystemspezifische Funktion meinst?

Link zu diesem Kommentar
Auf anderen Seiten teilen

kannst du mir kurz sagen was du mit betriebssystemspezifische Funktion meinst?
Eine Funktion, die nicht Bestandteil des C++-Standards ist, sondern als Bestandteil einer Programmierschnittstelle eines bestimmten Betriebssystems angeboten wird. Unter Windows z.B. kannst du die Sharing-Rechte mit der API-Funktion CreateFile regeln.

jedoch wäre es mir lieber, wenn ich filebuf trotzdem weiter benutzen könnte.
Wie gesagt, das, was du da machen willst, geht mit Standard-C++ nicht. Den Standard verlassen oder auf die Funktionalität verzichten, du musst dich entscheiden.
Link zu diesem Kommentar
Auf anderen Seiten teilen

Das ist nicht die open-Methode, sondern der Konstruktor. Der MSDN-Eintrag scheint sich auf MSVC6 zu beziehen, und auch ausdrücklich auf <fstream.h>, den veralteten Header. Vielleicht war das eine proprietäre Erweitung.

Ja ich weiß, ich hab den Konstruktor gepostet weil sich der Open Artikel darauf bezieht :)

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang98/html/_iostream_ofstream.3a3a.open.asp

Aber mit fstream.h geht es tatsächlich.

@Kitty82

Du kannst den Fehler so nicht beheben, weil das Problem ist das es in der Form nicht unterstüzt wird. Der Parameter existiert nicht für std::ofstream.

Die einzige Möglichkeit wäre das zu machen was Klotzkopp sagt und statt fstream fstream.h einzubinden. Dann benutzt du aber eine veraltete Header die nicht dem aktuellen standard entspricht.

***EDIT: Jetzt würde mich dochmal interessieren wie ich mich vertippt habe das mir das Forum anstatt Klotzkopp ****kopp geschrieben hat :D

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 4 Wochen später...

Hallo,

ich habe euren Rat befolgt und habe CreateFile bentutz.


//...

HANDLE hlock = CreateFile(pathFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
mit
if(!LockFile(hlock,0,0,1,0) )
überprüfe ich, ob die Datei gelockt ist. Das klappt alles wunderbar! Daher lese ich mit ReadFile die Dateien so ein:
int fileSize = GetFileSize(hlock, NULL);

char *szInhalt = new char[fileSize];


OVERLAPPED info;

info.hEvent = 0;

info.Internal = (DWORD)0;

info.InternalHigh = (DWORD)0;

info.Offset = (DWORD)0;

info.OffsetHigh = (DWORD)0;

ReadFile(lockHandle, szInhalt, fileSize, &r, &info);
Auch hier habe ich keine Probleme. und mit WriteFile die Dateien aus.
CString text;

//...

int fileSize = text.GetLength();

char *Buffer = new char[fileSize];

strcpy(Buffer, text);


OVERLAPPED info;

info.hEvent = 0;

info.Internal = (DWORD)0;

info.InternalHigh = (DWORD)0;

info.Offset = (DWORD)0;

info.OffsetHigh = (DWORD)0;


int erfolgreich = WriteFile(hlock, Buffer, fileSize, &w, &info);

Diese Datei soll komplett überschrieben werden. Kein "alter" Inhalt mehr vorhanden sein und der neue text somit reingeschrieben werden.

hier kurz ne beschreibung, was das programm macht, damit ihr mich evtl. besser versteht:

Das PRogramm soll unter anderem Informationen über ein bestimmtes Gerät beinhalten. Diese Informationen stehen immer in einer Datei. Jedes Gerät hat eine Datei. Je nachdem welches Gerät ausgewählt wird, wird die dazugehörige datei geöffnet (und gelockt) und die daten eingelsen um sie dann anschliesend dem benutzer zu anzuzeigen. jetzt können sich einige Werte ändern und der Benutzer kann somit die werte anpassen. Sobald er den neuen wert eingegeben+bestätigt hat, wird dieser wert in die datei geschrieben (WriteFile). daher darf kein alter inhalt mehr vorhanden sein.

jetzt ist oft das problem, dass er einfach die Dateien nicht immer vollständig schreibt. Gehe ich mit dem Debug schritt für schritt die gleichen(!) schritte durch, schreibt er es richtig. manchmal kommt es vor, dass er die dateien gleich richtig hineinschreibt. Was noch auftritt ist, dass wenn ich die Daten herausschreibe, er noch alten Inhalt in der datei hat. Sprich das neue wird reingeschrieben und unten drunter, noch etwas altes. gehe ich mit dem debug dort hin und schaue mir an, was er als buffer mitgegeben bekommt, stimmt es. er schreibt es aber trotzdem falsch raus. Woran kann das liegen?

dachte mit OVERLAPPED gebe ich ihm an, an welcher stelle er anfangen soll zu schreiben und mit CREATE_ALWAYS, dass er die Datei immer leert. :confused:

kann mir bitte hier jemand helfen?

wäre für jede hilfe sehr dankbar!!!

Danke!!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du hast Recht, so, wie du es machst, sollte es auch mit OVERLAPPED funktionieren. Prüfst du den Inhalt der Datei, während sie noch geöffnet ist? Dann kann es daran liegen, dass die zu schreibenden Daten noch im Cache liegen. Versuch bitte mal nach dem Schreiben FlushFileBuffers aufzurufen oder die Datei mit FILE_FLAG_NO_BUFFERING zu öffnen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du hast Recht, so, wie du es machst, sollte es auch mit OVERLAPPED funktionieren.

Aber besser wäre trotzdem SetFilePointer?

Prüfst du den Inhalt der Datei, während sie noch geöffnet ist?

Ehrlich gesagt, nein. Dachte, da er sie mit CREATE_ALWAYS öffnet, kann da nix mehr drin stehen...

Versuch bitte mal nach dem Schreiben FlushFileBuffers aufzurufen oder die Datei mit FILE_FLAG_NO_BUFFERING zu öffnen.

okay, werde das dann mal versuchen. meld mich dann wieder. schon mal *DANKE, für deine Hilfe* :byby: !

Link zu diesem Kommentar
Auf anderen Seiten teilen

habe es jetzt nun mit dem FlushFileBuffers vesucht. Erhalte immer true zurück. Jedoch klappt das trotzdem nicht. Ich verzweifle langsam. Weiss nicht woran es liegt. Ich überprüfe jedesmal was WriteFile mit Buffer übergeben wird und es stimmt IMMER, jedoch schreibt er ab und zu falsch raus. Woran kann es denn noch liegen? Wenn doch der inhalt des Buffers zu 1000% stimmt, aber er falsch rausschreibt ... :confused: :confused:

hast du eine vermutung??

Link zu diesem Kommentar
Auf anderen Seiten teilen

Um das nochmal für mich zu rekapitulieren:

Du öffnest eine Datei und liest sie aus. Danach schließt du die Datei wieder und öffnest sie erneut mit CREATE_ALWAYS und schreibst neue Daten in sie rein.

Am Ende fehlen aber Daten die du in die Datei geschrieben hast. Richtig so?

Wenn ja hast du mal überprüft was dir WriteFile zurückliefert wenn du die Datei füllst bzw. was in lpNumberOfBytesWritten drinsteht?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Um das nochmal für mich zu rekapitulieren:

Du öffnest eine Datei und liest sie aus. Danach schließt du die Datei wieder und öffnest sie erneut mit CREATE_ALWAYS und schreibst neue Daten in sie rein.

Am Ende fehlen aber Daten die du in die Datei geschrieben hast. Richtig so?

Wenn ja hast du mal überprüft was dir WriteFile zurückliefert wenn du die Datei füllst bzw. was in lpNumberOfBytesWritten drinsteht?

hm naja fast ;)

ich versuche es nochmal zu erklären. ich locke eine Datei mit CreateFile, lese sie aus mit ReadFile, lasse sie geöffnet (gelockt), dann versuche ich mit WriteFile hineinzuschreiben. Dabei entstehen felhler. nicht immer. Ab und zu klappt es obwohl ich immer kontrolliere, was WriteFile übermittelt bekommt und der Buffer ist IMMER richtig gefüllt.

Bsp: (vielleicht wird es dadurch klarer?)

er soll in die datei "A B C D\n E F G H..." schreiben. Er schreibt: "A B C D\n E F G H...D\n E F G H..." Ab einer bestimmten position schreibt er wieder das gleiche. Widerholt es aber nur 1mal.

habe ich es nun besser formuliert? :(

zurückliefern tut WriteFile immer true.

//edit: was ich noch vergessen hatte: lpNumberOfBytesWritten hat immer den selben Wert wie nNumberOfBytesToWrite - also müsste das auch okay sein

Link zu diesem Kommentar
Auf anderen Seiten teilen

Aber du hast oben doch geschrieben das du sie zum füllen mit Create_Allways öffnen würdest? Dazu musst du sie doch zwangsläufig nach dem Lesen neu öffnen.

Außerdem ist das meiner Meinung nach der bessere Weg anstatt den Dateizeiger wieder auf Anfang zu setzten und hoffen das alles Überschrieben wird.

Nach deiner Erklärung würde ich vermuten das WriteFile entweder 2 mal mit den selben Daten aufgerufen wird und eshalb 2 mal das Selbe in der Datei steht oder das es manchmal halt noch von vorher drin steht und nicht überschrieben wurde.

Link zu diesem Kommentar
Auf anderen Seiten teilen

:( entweder verstehst du mich nicht, oder ich habe was falsch verstanden.

ich öffne die Datei mit CreateFile. Dort übergebe ich das CREATE_ALWAYS. Dass wenn die Datei geöffnet wird, den Inhalt immer löscht. Nachdem sie geöffnet ist, lese ich die Daten ein. Die Datei bleibt geöffnet/gelockt (Abfrage erfolgt durch

if(!LockFile(lockFileHandle,0,0,1,0) )

), da in diesem Zeitpunkt niemand darauf zugreifen darf. Wenn z.Bsp. Werte geändert wurden, wird danach gleich wieder in diese (noch offene) Datei geschrieben. Da CREATE_ALWAYS muss diese ja leer sein und somit kann ich mit WriteFile die neuen Werte hineinschreiben.

Wenn ich nun die Datei schließe und erneut öffne um darin zu schreiben, kann in diesem kurzen Augenblick jemand darauf zugreifen. Ich hab hier die Angaben, dass dies nie geschehen darf. Daher meine Idee, die Datei solange gelockt zu lassen, bis ich mit dem reinschreiben fertig bin.

Wenn das nun soweit alles okay ist, darf er beim Reinschreiben nicht seinen text davorschieben oder anhängen. Oder gilt dann hier in diesem Fall dann das CREATE_ALWAYS nicht mehr?

Link zu diesem Kommentar
Auf anderen Seiten teilen

hehe ja irgendwie verstehen wir uns falsch :)

ich dachte du liest erst Daten aus dieser Datei ein und schreibst die Datei dann neu. Das würde ja nicht funktionieren wenn du sie direkt mit Create_Allways öffnen würdest weil sie ja dann leer wäre und du nichts aus ihr lesen könntest. Aber anscheined willst du sie nur neu schreiben und holst die Daten woanders her.

Aber so ganz durchblicken tu ich ehrlich gesagt immer noch nicht ;)

Wenn ich nun die Datei schließe und erneut öffne um darin zu schreiben, kann in diesem kurzen Augenblick jemand darauf zugreifen. Ich hab hier die Angaben, dass dies nie geschehen darf. Daher meine Idee, die Datei solange gelockt zu lassen, bis ich mit dem reinschreiben fertig bin.

Wieso schließt du die Datei denn überhaupt wenn du mit dem schreiben noch nicht fertig bist?

PS: Falls du ICQ hast kannst du auch versuchen es mir da nochmal zu erklären, geht vielleicht einfacher ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

hehe ja irgendwie verstehen wir uns falsch :)

Wieso schließt du die Datei denn überhaupt wenn du mit dem schreiben noch nicht fertig bist?

Du meintest, "Dazu musst du sie doch zwangsläufig nach dem Lesen neu öffnen." um dir zu erklären, warum ich das nicht so mache, hab ich das geschrieben. also ich schließe die datei nicht, bevor ich darein geschrieben habe. öffnen ->locken ->lesen ->schreiben->entlocken & schließen

PS: Falls du ICQ hast kannst du auch versuchen es mir da nochmal zu erklären, geht vielleicht einfacher

bin im geschäft, dürfen das nicht benutzen. daher wenn, dann erst heute abend so gegen 22uhr. :confused:

Link zu diesem Kommentar
Auf anderen Seiten teilen

ehem :eek ... es funktioniert ... :( :( :confused:

moment, hier mal der Code (damti du dich überzeugen kannst):

lockFileHandle = CreateFile(pathForFile, GENERIC_READ | GENERIC_WRITE, 

                                FILE_SHARE_READ | FILE_SHARE_WRITE, 0, 

                                CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);


if(!LockFile(lockFileHandle,0,0,1,0) ) 

{

  AfxMessageBox("You can't select this scanner!

                       \nSomeone else is using it! Try later again", 

                       MB_ICONINFORMATION | MB_OK);			


//... ein anderes Gerät wird ausgewählt und 

//dadurch diese funktion hier ebenfalls. 

// nur wenn die datei nicht gelocked ist, 

//wird mit UpdateScannerData weitergemacht

}


UpdateScannerData(pathForFile);  //hier wird überprüft, ob sich die neuen Daten von den alten unterscheiden. 
und die funktion UpdateScannerData(CString path) sieht dann wie folgt aus:

CString text;

DWORD r;

int pos_blanc =0,

    end_line =0;

//... 


int fileSize = GetFileSize(lockFileHandle, NULL);

char *szInhalt = new char[fileSize];

OVERLAPPED info;


info.hEvent = 0;//lockFileHandle;

info.Internal = (DWORD)0;

info.InternalHigh = (DWORD)0;

info.Offset = (DWORD)0;

info.OffsetHigh = (DWORD)0;


//neue Daten werden von der Datei eingelesen:

ReadFile(lockFileHandle, szInhalt, fileSize, &r, &info);

das funktioniert. habe ich schon getestet. und nun? :( bist nun auch fix und fertig? :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Um ehrlich zu sein ja, denn meiner Meinung nach dürfte es nicht funktionieren da die Datei ja beim öffnen durch eine neue ersetzt wird.

Was gibt dir denn GetFileSize zurück? Laut MSDN:

Files

When creating a new file, the CreateFile function performs the following actions:

Combines the file attributes and flags specified by dwFlagsAndAttributes with FILE_ATTRIBUTE_ARCHIVE.

Sets the file length to zero.

Copies the extended attributes supplied by the template file to the new file if the hTemplateFile parameter is specified.

müsste das ja 0 sein.

Link zu diesem Kommentar
Auf anderen Seiten teilen

kein Problem. ich hab gerade mal schnell folgendes Programm zusammengetippt und da wenn ich das mehrmals hintereinander laufen lasse ist die Dateigröße immer 0 und es kann nichts aus der Datei gelesen werden:


#include <stdio.h>
#include <windows.h>


int main(){

HANDLE hFile;
int iSize;
char szInhalt[100];
DWORD dwAnz;


hFile = CreateFile("c:\\test.txt",GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

iSize = GetFileSize(hFile, NULL);
printf ("Dateigroeße: %i\n",iSize);
ReadFile(hFile, szInhalt, iSize, &dwAnz, 0);
printf ("%i Bytes gelesen: %s\n\n",dwAnz,szInhalt);
WriteFile(hFile,"Teeeeeeest",10,&dwAnz,0);
printf ("%i Bytes geschrieben",dwAnz);
CloseHandle(hFile);
return 0;
}
[/PHP]

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...