Kitty82 Geschrieben 15. November 2005 Geschrieben 15. November 2005 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 Zitieren
Klotzkopp Geschrieben 15. November 2005 Geschrieben 15. November 2005 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. Zitieren
Guybrush Threepwood Geschrieben 15. November 2005 Geschrieben 15. November 2005 Laut MSDN hat ofstream::open einen dritten Paramter der auch mit filebuff::sh_none gefüllt werden kann. Wenn ich es jedoch ausprobiere bekomme ich den selben Fehler... MSDN Zitieren
Klotzkopp Geschrieben 15. November 2005 Geschrieben 15. November 2005 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. Zitieren
Kitty82 Geschrieben 15. November 2005 Autor Geschrieben 15. November 2005 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? Zitieren
Klotzkopp Geschrieben 15. November 2005 Geschrieben 15. November 2005 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. Zitieren
Guybrush Threepwood Geschrieben 15. November 2005 Geschrieben 15. November 2005 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 Zitieren
Kitty82 Geschrieben 15. November 2005 Autor Geschrieben 15. November 2005 alles klar. danke nochmals! werde mir dann mal CreateFile ansehen ... Zitieren
Kitty82 Geschrieben 14. Dezember 2005 Autor Geschrieben 14. Dezember 2005 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!! Zitieren
Klotzkopp Geschrieben 14. Dezember 2005 Geschrieben 14. Dezember 2005 dachte mit OVERLAPPED gebe ich ihm an, an welcher stelle er anfangen soll zu schreibenNein, mit OVERLAPPED regelst du asynchrone Dateizugriffe. Schau dir mal SetFilePointer an. Zitieren
Kitty82 Geschrieben 14. Dezember 2005 Autor Geschrieben 14. Dezember 2005 Danke, klotzkopp für die schnelle Antwort! Werde mir nun mal SetFilePointer ansehen. würde OVERLAPPED nun gar nicht gehen? Habe bei offset ja 0 eingesetzt und somit müsste er doch auch bei 0 anfangen? :confused: Zitieren
Klotzkopp Geschrieben 14. Dezember 2005 Geschrieben 14. Dezember 2005 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. Zitieren
Kitty82 Geschrieben 14. Dezember 2005 Autor Geschrieben 14. Dezember 2005 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: ! Zitieren
Kitty82 Geschrieben 14. Dezember 2005 Autor Geschrieben 14. Dezember 2005 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?? Zitieren
Guybrush Threepwood Geschrieben 14. Dezember 2005 Geschrieben 14. Dezember 2005 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? Zitieren
Kitty82 Geschrieben 14. Dezember 2005 Autor Geschrieben 14. Dezember 2005 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 Zitieren
Guybrush Threepwood Geschrieben 14. Dezember 2005 Geschrieben 14. Dezember 2005 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. Zitieren
Kitty82 Geschrieben 14. Dezember 2005 Autor Geschrieben 14. Dezember 2005 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? Zitieren
Guybrush Threepwood Geschrieben 14. Dezember 2005 Geschrieben 14. Dezember 2005 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 Zitieren
Kitty82 Geschrieben 14. Dezember 2005 Autor Geschrieben 14. Dezember 2005 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: Zitieren
Guybrush Threepwood Geschrieben 14. Dezember 2005 Geschrieben 14. Dezember 2005 Also jetzt bin ich total verwirrt öffnen ->locken ->lesen ->schreiben->entlocken & schließen wie kannst du etwas aus der Datei lesen wenn du sie mit create_allways öffnest? Naja bis 22Uhr sollte sich das bestimmt auch so lösen lassen, ansonsten bin ich eigentlich meistens online Zitieren
Kitty82 Geschrieben 14. Dezember 2005 Autor Geschrieben 14. Dezember 2005 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? Zitieren
Guybrush Threepwood Geschrieben 14. Dezember 2005 Geschrieben 14. Dezember 2005 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. Zitieren
Kitty82 Geschrieben 14. Dezember 2005 Autor Geschrieben 14. Dezember 2005 okay, ich muss erstmal mittagspause machen. das programm läuft nun gar nimmer gescheit. muss schauen, was ich zuletzt geändert habe. danke erstmal für deine hilfe. wenn wieder alles so läuft, wie es war und ich hab immernoch fehler, meld ich mich dank dir für deine hilfe :e@sy Zitieren
Guybrush Threepwood Geschrieben 14. Dezember 2005 Geschrieben 14. Dezember 2005 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] Zitieren
Empfohlene Beiträge
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.