Tim Brays Artikel "Saving Data Safely" ließ mich mit offenen Fragen. Heute ist es mehr als einen Monat alt und ich habe keine Nachfolge gesehen, also habe ich beschlossen, das Thema hier anzusprechen.ext4/fsync Situation unklar in Android (Java)
Ein Punkt des Artikels ist, dass FileDescriptor.sync() aufgerufen werden sollte, um bei der Verwendung von FileOutputStream auf der sicheren Seite zu sein. Zuerst war ich sehr irritiert, weil ich in den 12 Jahren, in denen ich Java mache, nie einen Java-Code gesehen habe, der eine Synchronisierung durchführt. Vor allem, da das Arbeiten mit Dateien eine ziemlich einfache Sache ist. Auch das Standard-JavaDoc von FileOutputStream hat nie auf eine Synchronisierung hingewiesen (Java 1.0 - 6). Nach einigen Nachforschungen stellte ich fest, dass ext4 möglicherweise das erste Mainstream-Dateisystem ist, das synchronisiert werden muss. (Gibt es andere Dateisysteme, bei denen explizite Synchronisierung geraten ist?)
ich einige allgemeine Gedanken über die Angelegenheit zu schätzen wissen, aber ich habe auch einige spezifische Fragen:
- Wann wird Android tun, um die Synchronisierung auf das Dateisystem ? Dies könnte periodisch sein und zusätzlich auf Lebenszyklusereignissen basieren (z. B. geht der Prozess einer Anwendung in den Hintergrund).
- Bearbeitet FileDescriptor.sync() die Synchronisierung der Metadaten? Das synchronisiert das Verzeichnis der geänderten Datei. Vergleichen Sie mit FileChannel.force().
- Normalerweise schreibt man nicht direkt in den FileOutputStream. Hier ist meine Lösung (sind Sie einverstanden?):
FileOutputStream fileOut = ctx.openFileOutput(file, Context.MODE_PRIVATE); BufferedOutputStream out = new BufferedOutputStream(fileOut); try { out.write(something); out.flush(); fileOut.getFD().sync(); } finally { out.close(); }
Ich hätte erwartet, dass die flush() sicherstellen, dass alles auf die Disc geschrieben wird - im Wesentlichen durch den Aufruf von sync(). Ist das nicht der Fall? –
@a_horse_with_no_name: Nein, ist es nicht. _flush_ und _sync_ sind zwei verschiedene Operationen: flush spült nur Zwischenpuffer; Die Synchronisierung schreibt tatsächlich in den Speicher. Siehe z.B. http://stackoverflow.com/questions/2340610/difference-between-fflush-and-fsync – sleske
@sleske: Danke für die Klarstellung! –