Datei löschen
-
Hi,
Ich habe mich schon lange mal gefragt, wie man (z.B. hier: in C) eine Datei löscht - und zwar so, dass auch die Daten überschrieben werden - sodass die Datei also wirklich nicht mehr zugreifbar/lesbar ist.
Eine Idee von mir wäre, die Datei zum Lesen zu öffnen, um erstmal die Länge zu ermitteln; anschließend schreibend öffnen und über die komplette Länge der Datei Nullbytes schreiben; danach dann einfach löschen mit remove().
Problem ist, dass ich nicht genau weiß, wie ich jetzt Überschreibe.
Laut C-Standard: "truncate to zero length" (Beim Öffnen im Modus w bzw. w+)Also wird hier wirklich nur die Länge gleich 0 gesetzt und sonst bleiben die ganzen Daten in der Datei noch drin? Dann müsste das mit dem Überschreiben ja gehen.
Oder löscht der die Datei wirklich und erstellt einfach irgendwo anders eine neue Datei mit dem selben Namen(was das Überschreiben natürlich sinnlos machen würde..)?
Habe per googeln dazu bisher nichts gefunden; wär nett, wenn mir da jemand weiterhelfen könnte
-
Dateien kannst du mit unlink oder remove entfernen. unlink gibts auf POSIX-Systemen, remove gibt in stdio.h.
Klar kannst du die Datei mit Nullen überschreiben, wenn du das möchtest. Das geht so wie du geschrieben hast. Was bei truncate to zero length passiert, weiß ich nicht. Aber öffne doch einfach die Datei ohne truncate, überschreibe und lösche sie anschließend.
EDIT: offensichtlich geht das nicht, oder nicht so einfach. Wenn man die Datei mit "a" als Argument öffnet, wird immer ans Ende geschrieben, egal wo der File Position Indicator hinzeigt. Hm.
-
Dann öffne im Modus "r+".
-
Tja, so siehts aus. Danke. Die Referenz ist da nicht gerade aussagekräftig:
mode Meaning Explanation Action if File already exists "r+" read extended Open a file for read/write read from start
Es gibt einen Hinweis, dass das mit append nicht funktioniert. Ich finde aber gerade die Stelle nicht. Naja, egal. Problem ist ja gelöst.
-
Bei "a+" kann man vom Anfang lesen, aber immer nur am Ende anhängen.
Bei "w+" wird die Datei vorher gelöscht/auf Länge 0 gesetzt, man kann aber auch (schon geschriebene) Daten lesen.
Bei "r+" kann man auch schreiben.Beim Umschalten zwischen lesen und schreiben ist aber ein
fflush
bzw. ein Neusetzen des Dateizeigers (fseek, fsetpos, rewind) nötig.
-
Ja, "r+b" ist genau, was ich suche!
Habe es gerade getestet und alles funktioniert.
Danke für die Antworten.
-
In dem Zusammenhang:
Weiß jemand vielleicht, wie ich schnell die Länge einer Datei ermitteln kann?ftell() funktioniert bei mir nicht bei großen Dateien, da es einen long-Wert zurückgibt und auf meinem System ist long = int = 4byte.
(Ich kann also nur Dateigrößen ~2GB mit ftell() herausfinden)Gibt es da eine bessere Möglichkeit, als "naiv" hochzuiterieren und EOF zu suchen?
Ich hatte schon probiert mit fseek() einfach in 100MB schritten oder so zu suchen, aber damit finde ich das EOF nicht, wenn ich über die tatsächliche Grenze "rüberspringe".
Im Netz finde ich überall nur diese ftell()-Methode.
Wäre dankbar für einen Tipp
-
Wenn dein System so große Dateien unterstützt, dann gibt es auch eine Variante von
ftell
, die das unterstützt.Die heißt dann nur anders: ftello(), ftello64(), _ftelli64 oder ???
-
hm.. ja,
long long _ftelli64();
gibts bei mir.
Ist diese Funktion überhaupt im C-Standard? Unter cpp-reference z.B. gibt es die nicht, ist aber in der <stdio.h> definiert.
Danke für die Antwort
-
triarii schrieb:
Ist diese Funktion überhaupt im C-Standard? Unter cpp-reference z.B. gibt es die nicht, ist aber in der <stdio.h> definiert.
Nichts aber. Was bei dir in stdio.h vorkommt, ist nicht alles Standard, bloß weil der Compilerhersteller meinte, dort in diesen Standard-Header noch was reinzustecken.
Du musst auf Nicht-Standard ausweichen, d.h. du wirst plattformabhängig.
ftell ist eine leidige Geschichte, das bringt nichts.Nicht-Windows-Systeme:
#define _FILE_OFFSET_BITS 64 #include <sys/stat.h> int64_t fsize(const char *filename) { struct stat st; if (stat(filename, &st) == 0) return st.st_size; return -1; }
Windows-Systeme:
GetFileSizeEx
-
ftell ist eine leidige Geschichte, das bringt nichts.
Sollte Dateizeiger ans Ende der Datei und dann ftell nicht relativ zuverlässig sein ?
-
- im Textmode wird unter Windows \r\n als ein Zeichen gezählt
- im Binmode sagt der Standard "A binary stream need not meaningfully support fseek calls with a whence value of SEEK_END."
- weiterhin gibt es wegen long auf den meisten Systemen die Begrenzung auf 2 GB Dateigröße
--> alles Gründe, das leidige ftell zu meiden
-
Oh, ok. Bisschen schockierend, dass der Standard keine zuverlässige Methode liefert ?
Also ist die Profivariante ist dann : GetFileSizeEx ?
Blöde Frage, aber wie arbeitet GetFileSizeEx intern ? Ich meine die Api Funktionm kann ja auch nicht zaubern ?
-
Bis 2 gb hat ftell bei mir immer funktioniert. Danach musste ich dann .log-1, log-2. etc machen.
EDIT:
mit mitzählen natürlch