 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
wilfried polenz Guest
|
Posted: Thu Sep 07, 2006 1:50 am Post subject: Umgang mit Dateien |
|
|
Hallo,
ich wollte eine TextDatei öffnen den Dateizeiger auf eine bestimmte
Stelle vom Dateiende her gerechnet setzen und dann abspeichern.
die neue datei sollte dann um dieses Stück abgeschnitten werden.
doch das funktioniert nicht. woran liegt's ?
fstream myFile("ABC.TXT",ios::out|ios::app);
//datei öffnen
myFile.seekp(-50,ios::end);
//dateizeiger soll 50 zeichen vor eof gesetzt werden
myFile.close();
//jetzt denke ich mir ist die datei abgeschnitten
besten dank für eventuelle antwort,
wilfried |
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Thu Sep 07, 2006 2:41 am Post subject: Re: Umgang mit Dateien |
|
|
wilfried polenz <wilfried.pz@t-online.de> writes:
| Quote: | ich wollte eine TextDatei öffnen den Dateizeiger auf eine bestimmte
Stelle vom Dateiende her gerechnet setzen und dann abspeichern.
die neue datei sollte dann um dieses Stück abgeschnitten werden.
doch das funktioniert nicht. woran liegt's ?
|
Deine Erwartungen sind falsch.
| Quote: | fstream myFile("ABC.TXT",ios::out|ios::app);
//datei öffnen
myFile.seekp(-50,ios::end);
//dateizeiger soll 50 zeichen vor eof gesetzt werden
|
Die aktuelle Position wurde schon an diese Stelle gesetzt, aber an der
Datei wird damit nichts verändert.
Ich denke, dass für eine portable Lösung Deines Problems den Inhalt
der Datei ohne die letzten 50 Zeichen kopieren musst. |
|
| Back to top |
|
 |
Daniel Albuschat Guest
|
Posted: Thu Sep 07, 2006 9:11 am Post subject: Re: Umgang mit Dateien |
|
|
wilfried polenz wrote:
| Quote: | Hallo,
ich wollte eine TextDatei öffnen den Dateizeiger auf eine bestimmte
Stelle vom Dateiende her gerechnet setzen und dann abspeichern.
die neue datei sollte dann um dieses Stück abgeschnitten werden.
doch das funktioniert nicht. woran liegt's ?
fstream myFile("ABC.TXT",ios::out|ios::app);
//datei öffnen
myFile.seekp(-50,ios::end);
//dateizeiger soll 50 zeichen vor eof gesetzt werden
myFile.close();
//jetzt denke ich mir ist die datei abgeschnitten
besten dank für eventuelle antwort,
|
Hallo Wilfried,
Ein Dateizeiger funktioniert anders, als du es erwartet hast. Ein
Dateizeiger ist lediglich die aktuelle Position, in der eine Datei
gelesen oder geschrieben wird. Das Ändern des Dateizeigers ändert die
Datei nicht[1]. Es wird lediglich bestimmt, an welcher Stelle man
"gerade steht".
Um eine Datei auf die letzten 50 Zeichen selbiger zu beschneiden, musst
du dafür wie folgt vorgehen:
- Datei mit dem Flag ios::in öffnen.
- Lesezeiger auf -50 ab ios::end setzen.
- 50 Zeichen aus der Datei in einen Puffer lesen.
- Die Datei schließen.
- Datei erneut öffnen, diesmal mit den Flags ios::out | ios::trunc,
damit sie "geleert" wird.
- Den Puffer aus 50 Zeichen in die Datei schreiben.
- Datei schließen (geschieht auch implizit im Destruktor).
MfG,
Daniel
[1] In dem Fall, dass der Schreibzeiger auf eine Position hinter dem
Streamende gesetzt wird, werden alle Bytes vom Ende des Streams bis
zum neuen Ende auf 0 gesetzt und somit doch die Datei geändert. |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Thu Sep 07, 2006 3:15 pm Post subject: Re: Umgang mit Dateien |
|
|
wilfried polenz wrote:
| Quote: | ich wollte eine TextDatei öffnen den Dateizeiger auf eine
bestimmte Stelle vom Dateiende her gerechnet setzen und dann
abspeichern. die neue datei sollte dann um dieses Stück
abgeschnitten werden.
doch das funktioniert nicht. woran liegt's ?
|
Zwei Probleme:
| Quote: | fstream myFile("ABC.TXT",ios::out|ios::app);
//datei öffnen
myFile.seekp(-50,ios::end);
//dateizeiger soll 50 zeichen vor eof gesetzt werden
|
Ist undefiniertes Verhalten. Du kannst nicht zu einer beliebigen
Stelle in einem Text-Datei seeken. Bei Text-Dateien muss der
erste Parameter stetts 0 sein.
| Quote: | myFile.close();
//jetzt denke ich mir ist die datei abgeschnitten
|
Und du hast wohl nichts in der Datei geändert. In Allgemein gibt
es keine Möglichkeit in der Norm, Dateien kleiner zu machen.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Mon Sep 11, 2006 9:27 pm Post subject: Re: Umgang mit Dateien |
|
|
Thomas Rachel wrote:
| Quote: | Daniel Albuschat wrote:
[1] In dem Fall, dass der Schreibzeiger auf eine Position hinter dem
Streamende gesetzt wird, werden alle Bytes vom Ende des Streams bis
zum neuen Ende auf 0 gesetzt und somit doch die Datei geändert.
Aber erst bei einem write(). Ansonsten hilft (f)truncate()
|
....und all das nur unter bestimmten Betriebssystemen.
Unter DOS erstellt dir
s.seekp(100000, ios::end);
s.write("", 1);
eine Datei, die das enthält, was zufällig gerade an der Stelle auf der
Platte stand. Das ist zwar praktisch, um undelete zu simulieren, aber
ansonsten eher hinderlich.
Ich würde mich also in einem portablen Programm auf kein solches
Verhalten verlassen.
Stefan |
|
| Back to top |
|
 |
Marcel Müller Guest
|
Posted: Mon Sep 11, 2006 10:49 pm Post subject: Re: Umgang mit Dateien |
|
|
Stefan Reuther wrote:
| Quote: | Unter DOS erstellt dir
s.seekp(100000, ios::end);
s.write("", 1);
eine Datei, die das enthält, was zufällig gerade an der Stelle auf der
Platte stand. Das ist zwar praktisch, um undelete zu simulieren, aber
ansonsten eher hinderlich.
Ich würde mich also in einem portablen Programm auf kein solches
Verhalten verlassen.
|
Ack. Und Wenn die Plattform Sparse Files unterstützt passieren noch viel
wunderlichere Dinge...
Der nie geschriebene Dateiinhalt ist undefiniert und darf keinesfalls
vor einem Schreibzugriff gelesen werden. Alles andere liefert
undefiniertes Verhalten des Lese-Befehls (Nullen, Zufallszahlen,
Lesefehler, was auch immer).
Marcel |
|
| Back to top |
|
 |
Marcel Müller Guest
|
Posted: Mon Sep 11, 2006 10:52 pm Post subject: Re: Umgang mit Dateien |
|
|
kanze wrote:
| Quote: | myFile.seekp(-50,ios::end);
//dateizeiger soll 50 zeichen vor eof gesetzt werden
Ist undefiniertes Verhalten. Du kannst nicht zu einer beliebigen
Stelle in einem Text-Datei seeken. Bei Text-Dateien muss der
erste Parameter stetts 0 sein.
|
Das stimmt meines Wissens nicht ganz.
Es sind auch all jene Werte erlaubt, die zuvor mit tellp() abgefragt wurden.
Marcel |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Tue Sep 12, 2006 2:52 pm Post subject: Re: Umgang mit Dateien |
|
|
Daniel Albuschat wrote:
[...]
| Quote: | [1] In dem Fall, dass der Schreibzeiger auf eine Position hinter dem
Streamende gesetzt wird, werden alle Bytes vom Ende des Streams bis
zum neuen Ende auf 0 gesetzt und somit doch die Datei geändert.
|
Das ist überhaupt nicht garantiert. Die C++-Norm sagt nichts
darüber; da »A joint file position is maintained for both the
input sequence and the output sequence« könnte man fast denken,
dass ein seek hinter dem Streamende als Fehler betrachtet soll.
In Praxis denke ich, dass die meisten Implementierungen leiten
die seek einfach weiter am Betriebssystem, und also dass das
Verhalten dann hängt vom Betriebssystem an. (Was du beschreibst
entspricht Unix; bei den meisten anderen Betriebssystemen, die
ich gesehen habe, bekommt man wohl einen Fehler.)
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Tue Sep 12, 2006 3:01 pm Post subject: Re: Umgang mit Dateien |
|
|
Marcel Müller wrote:
| Quote: | kanze wrote:
myFile.seekp(-50,ios::end);
//dateizeiger soll 50 zeichen vor eof gesetzt werden
Ist undefiniertes Verhalten. Du kannst nicht zu einer beliebigen
Stelle in einem Text-Datei seeken. Bei Text-Dateien muss der
erste Parameter stetts 0 sein.
Das stimmt meines Wissens nicht ganz.
Es sind auch all jene Werte erlaubt, die zuvor mit tellp()
abgefragt wurden.
|
Nicht bei dieser Funktion. ostream::seekp ist überladen; bei der
Funktion mit zwei Parametern hat sogar die Rückgabe von tellp()
nicht den richtigen Typ. Du hast rechts, dass seekp mit einem
Parameter alle Rückgaben von tellp() nehmen kann (insofern
tellp() auf denselbem Objekt aufgerufen wurde, und kein close
noch open inzwischen stattgefunden ist). Wenn ich aber ios::end
(oder ios::beg oder ios::cur) angeben aber, darf der erste
Parameter nur 0 sein.
Auf einer Text-Datei. Habe ich die Datei mit ios::binary
geöffnet, dann ist es anders. Und das Verhalten von ios::end ist
überhaupt nicht definiert:-). (Funktionniert aber richtig auf
den meisten modernen Betriebssystemen.)
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
Thomas Rachel Guest
|
Posted: Sun Sep 17, 2006 9:43 pm Post subject: Re: Umgang mit Dateien |
|
|
Stefan Reuther wrote:
| Quote: | Thomas Rachel wrote:
Daniel Albuschat wrote:
[1] In dem Fall, dass der Schreibzeiger auf eine Position hinter dem
Streamende gesetzt wird, werden alle Bytes vom Ende des Streams bis
zum neuen Ende auf 0 gesetzt und somit doch die Datei geändert.
Aber erst bei einem write(). Ansonsten hilft (f)truncate()
...und all das nur unter bestimmten Betriebssystemen.
|
Stimmt - hatte ich verdrängt :-}
| Quote: | Unter DOS erstellt dir
s.seekp(100000, ios::end);
s.write("", 1);
eine Datei, die das enthält, was zufällig gerade an der Stelle auf der
Platte stand. Das ist zwar praktisch, um undelete zu simulieren, aber
ansonsten eher hinderlich.
|
Allerdings. BTDT - beides. Sowohl undelete als auch geärgert, weil mein
MinGW-gcc eine .exe mit potentiell vertraulichen Daten drin ausgespuckt
hat.
| Quote: | Ich würde mich also in einem portablen Programm auf kein solches
Verhalten verlassen.
|
Full ACK.
Thomas
--
"If you're killed in the Matrix, you die here?"
"The body cannot live without the mind."
Neo and Morpheus, "The Matrix" |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|