Mitten in Datei schreiben???
-
Hallo.
Ich hab hier so eine html-datei-erstell Funktion geschrieben.
Jetzt schreib ich also zuerst mal die Grundstruktur in diese Datei:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title> </title> <meta> </meta> </head> <body> <table> <tr> <td class="msg_no_head">NO:</td> <td class="msg_type_head">Msg type:</td> <td class="msg_desc_head">Description:</td> </tr><!--NEXT_ROW--> </table> </body> </html>Jetzt geht das so, dass ich die Zeichenanzahl bis
<!--NEXT_ROW-->einlese und dann den neuen String DAHIN, also an diese ausgewählte Position setzten will.
Den String den ich da hin setzten will sieht so aus:<tr><td>2</td><td>test</td><td>desc</td></tr>Wenn ich die Datei jetzt öffne, dann geht das ja nur bedingt, also lese oder schreib Zugriff mit entsprechenden ios_base::... parametern.
Das einzige was bis jetzt ging ist das dranhängen. Das sieht dann so aus:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title> </title> <meta> </meta> </head> <body> <table> <tr> <td class="msg_no_head">NO:</td> <td class="msg_type_head">Msg type:</td> <td class="msg_desc_head">Description:</td> </tr><!--NEXT_ROW--> </table> </body> </html><tr><td>2</td><td>test</td><td>desc</td></tr>Wie kann ich jetzt z.b. den Teil hier löschen:
<!--NEXT_ROW--> </table> </body> </html>Weil den kann man ja einlesen. Wenn ich den löschen könnte, dann könnte ich den neuen String an die Datei anhängen und dann das gelöschte wiederum hinten dran hängen. Dann hätte ich ja den neuen String mitten drin.
Oder geht das anders?
Wie kann ich also da zwischen rein schreiben?#EDIT#
Ein Zeiger auf den Anfang der Datei wäre super.
Ich hab alles versucht. Mit FILE und mit wofstream.
Ich bekomme keinen Zeiger auf die (verdammte) Datei.
Das muss doch irgendwie gehen!!!
#/EDIT#Gruß
Alex
-
Du kannst nichts aus einer Datei rauslöschen. Lies alles ein (vielleicht in ein vector<string> oder so), füge dann deine Zeile dort ein und schreibe die gesamte Datei wieder raus.
-
Braunstein schrieb:
Du kannst nichts aus einer Datei rauslöschen. Lies alles ein (vielleicht in ein vector<string> oder so), füge dann deine Zeile dort ein und schreibe die gesamte Datei wieder raus.
Du kannst nichts einfügen, aber überschreiben. Das heißt, Du kannst den Teil hinter dem Bereich, an dem Du schreiben möchtest einlesen, dann überschreiben und den eingelesen Part wieder hinten anfügen. Damit ersparst Du Dir das einlesen und wieder zurückschreiben des Bereichs, der vor dem eingefügten Bereich liegt.
Solltest Du etwas aus der Datei löschen, müsstest Du den dahinterliegenden Part nach vorne kopieren und die Daten anschließend verkürzen.
Das spart je nach Dateigröße viel Arbeit.
-
Hallo und Danke schon mal.
Also, dass man aus einer Datei nicht löschen kann, hab ich leider auch schon feststellen müssen. Meine Datei sieht schon so gut aus, und alles funktioniert, bis eben auf das, das ich gerne löschen würde.
@Braunstein:
Das mit einem Vektor machen, ist vielleicht nicht die beste Lösung, denn da könnte viel Output anfallen, den ich lieber gleich auf der Festplatte habe, als auf dem heap oder dem stack.@Xin:
Das ist gut, dass Du das sagst, denn ich habe noch mal(zum tausendsten Mal) über die MSDN Doc geschaut und habe feststellen müssen, dass CreateFile() die richtige Lösung für mich ist, denn man kann als Parameter ein OVERLAPPED stuct übergeben, die genau die Parameter beschreibt, die für mich wichtig sind, nämlich offset Parameter. So, ich hoffe das meintest Du so!
Ich habe es mit FILE und mit wofstrea/wifstream versucht, aber da geht nichts.Nebenbei gefragt, ist es möglich einen Zeiger auf eine Datei zu bekommen, die man dann z.B. in einen Zeiger auf TCHAR, also in TCHAR*, castet und so die Datei durchlaufen kann? Oder geht das nicht, weil die Datei ja auf der Festplatte liegt?
Gruß
Alex
-
Hi Mom!
DeineMutter schrieb:
Das ist gut, dass Du das sagst, denn ich habe noch mal(zum tausendsten Mal) über die MSDN Doc geschaut und habe feststellen müssen, dass CreateFile() die richtige Lösung für mich ist, denn man kann als Parameter ein OVERLAPPED stuct übergeben, die genau die Parameter beschreibt, die für mich wichtig sind, nämlich offset Parameter. So, ich hoffe das meintest Du so!
Öhh.. nö, ist halt die Frage, welche API man nutzen will. Ich nutze in der Regel die Standard C oder C++ API, womit ich OS unabhängig bleibe und da ich eh vorrangig Linux programmiere, dachte ich weniger an die MSDN

Aber gut, damit geht's sicherlich genauso gut.DeineMutter schrieb:
Ich habe es mit FILE und mit wofstrea/wifstream versucht, aber da geht nichts.
Bei FILE * wäre fseek Dein Stichwort, gefolgt von (iirc) ftruncate.
DeineMutter schrieb:
Nebenbei gefragt, ist es möglich einen Zeiger auf eine Datei zu bekommen, die man dann z.B. in einen Zeiger auf TCHAR, also in TCHAR*, castet und so die Datei durchlaufen kann? Oder geht das nicht, weil die Datei ja auf der Festplatte liegt?
Ein Zeiger zeigt auf einen Speicherbereich im RAM. Du musst die Daten erst in den RAM kopieren, damit Du draufzeigen kannst.
Grundsätzlich ist das Muster Datei öffnen, gewünschte Daten laden, Daten im Speicher modifizieren, Änderungen zurückschreiben (oder sehr häufig auch komplette Datei überschreiben), Datei schließen.
Du könntest Dir natürlich mit entsprechender Kenntnis in C++ eine Klasse schreiben, die als Dateizeiger fungiert und bei Zugriff dafür sorgt, dass die entsprechenden Daten vor dem Zugriff im RAM verfügbar sind und die Änderungen vor dem Schließen wieder in die Datei zurückschreibt.
Damit könntest Du das Öffnen, Schließen, Lesen und Schreiben natürlich automatisieren.
-
Hallo Xin.
Xin schrieb:
Bei FILE * wäre fseek Dein Stichwort, gefolgt von (iirc) ftruncate.
Das mit den FILE ist so eine Sache. Wenn ich eine Datei mit _wfopen() öffne, dann muss ich da diese mode parameter mit angeben. Diese Parameter besagen wie ich auf die Datei zugreife.
Das einzige nützliche flag in diesen Fall für mich wäreTEXT("ab+"), was bedeutet, dass die Funktion alles hinten dranhängt(a = append). Etwas anderes geht hier überhaupt nicht. Ich kann durch diese mode Parameter nur noch öffnen, schreiben, beides usw. Aber alles andere würde die Datei komplett löschen und den Inhalt der Datei will ich vorher auch nicht in den Speicher schreiben. Viel zu umständlich.
Jetzt ist das ja so, wenn ich also mit dem TEXT("ab+") öffne, dann setzt die Funktion fwrite() den file Zeiger immer vor das EOF Zeichen bzw. speichert es, löscht es und setzt es dann am Ende wieder dran.
Wenn ich jetzt mit seekf() die Zeigerposition setzt, also bevor ich fwrite() aufrufe, bringt mir das nichts, denn fwrite setzt den Zeiger ja wieder ans Ende.
Xin schrieb:
ftruncate
Ja, da gibt es noch sowas ähnliches, das auch in das mode-flag mit einfließt, nämlich
TEXT("t"). Aber das bewerkstelligt das setzten des Dateizeigers auf die Position 0, und überschreibt damit den vorherigen Text. Wenn ich das jetzt nicht falsch verstanden habe.
Wie auch immer. Mit CreateFile() und FileWrite() und der struct OVERLAPPED funktioniert alles bestens und ich kann vorhandenen Inhalt ersetzten. Genau so wie ich mir das vorgestellt habe!!
Gruß und Dank
Alex
-
DeineMutter schrieb:
Hallo Xin.
Xin schrieb:
Bei FILE * wäre fseek Dein Stichwort, gefolgt von (iirc) ftruncate.
Das mit den FILE ist so eine Sache. Wenn ich eine Datei mit _wfopen() öffne, dann muss ich da diese mode parameter mit angeben. Diese Parameter besagen wie ich auf die Datei zugreife.
Das einzige nützliche flag in diesen Fall für mich wäreTEXT("ab+"), was bedeutet, dass die Funktion alles hinten dranhängt(a = append).
Ich würde ja eher auf fopen() und "rb+" tippen. ^^