Frage

Tim Bray Artikel "Speichern von Daten sicher" hat mich mit offenen Fragen. Heute ist es mehr als ein Monat alt, und ich habe kein Follow-up auf sie gesehen, so dass ich hier das Thema anzusprechen entschieden.

Ein Punkt des Artikels ist, dass FileDescriptor.sync () soll auf der sicheren Seite zu sein, aufgerufen werden, wenn Fileoutputstream verwenden. Anfangs war ich sehr gereizt, weil ich nie einen Java-Code gesehen habe eine Synchronisierung während der letzten 12 Jahre zu tun ich Java tun. Vor allem, da mit Dateien fertig ist eine ziemlich einfache Sache. Auch der Standard-JavaDoc von Fileoutputstream nie Syncing (Java 1,0-6) angedeutet. Nach einigen Recherchen, dachte ich, ext4 eigentlich das erste Mainstream-Dateisystem erfordert Synchronisierung sein kann. (Gibt es andere Dateisysteme, bei denen explizite Synchronisierung geraten ist?)

Ich schätze einige allgemeine Gedanken zu diesem Thema, aber ich habe auch einige spezifische Fragen:

  1. Wann wird Android tun, um die Synchronisierung auf das Dateisystem? Dies könnte periodisch sein und zusätzlich auf Basis von Lebenszyklusereignissen (beispielsweise einen Prozess geht der App in den Hintergrund).
  2. Does FileDescriptor.sync () kümmern sich die Meta-Daten von Syncing? Das ist die Synchronisierung des Verzeichnisses der geändertenen Datei. Vergleichen Sie bis zu FileChannel.force ().
  3. Normalerweise muss man nicht direkt in den Outputstream schreiben. 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();
    }
    
War es hilfreich?

Lösung

Android wird die Synchronisierung durchführen, wenn er muss -. Wie wenn der Bildschirm schaltet sich aus, Abschaltung des Gerätes, usw. Wenn Sie schauen, nur bei „normalen“ Betrieb, explizite Synchronisierung von Anwendungen benötigt wird, um nie

Das Problem kommt, wenn der Benutzer die Batterie zieht von ihrem Gerät (oder tut einen Hard-Reset des Kernels), und Sie wollen Sie sicherstellen, keine Daten verloren gehen.

Das erste, was zu realisieren. Das Problem ist, wenn der Strom plötzlich verloren geht, so ein sauberes Herunterfahren kann nicht passieren, und die Frage, was in persistenten Speicher zu diesem Zeitpunkt geschehen wird

Wenn Sie nur eine einzige unabhängige neue Datei zu schreiben, ist es nicht wirklich wichtig, was Sie tun. Der Benutzer könnte die Batterie gezogen, während Sie in der Mitte des Schreibens waren, kurz bevor Sie begann zu schreiben, etc. Wenn Sie nicht synchron tun, es bedeutet nur, dass eine längere Zeit aus, wenn Sie fertig sind schriftlich bei dem Ziehen der Batterie die Daten verloren gehen.

Die große Sorge hier ist, wenn Sie eine Datei aktualisiert werden sollen. In diesem Fall, wenn Sie die Datei weiter lesen möchten Sie haben entweder die zurück Inhalte, oder die neue Inhalt. Sie wollen nicht, etwas auf halbem Weg geschrieben, oder verlieren die Daten.

bekommen

Dies wird häufig getan, indem die Daten in einer neuen Datei zu schreiben, und dann über die aus der alten Datei wechseln. Vor Ext4 wußte man, dass, sobald Sie eine Datei beendet hatten zu schreiben, weitere Operationen auf anderen Dateien nicht auf der Festplatte, bis die, das auf dieser Datei gehen, so dass Sie sicher die vorherige Datei löschen könnten oder auf andere Weise Operationen ausführen, die auf Ihre neue Datei abhängen wird voll geschrieben.

Doch jetzt, wenn Sie die neue Datei schreiben, löschen Sie die alten und die Batterie gezogen wird, wenn Sie zum nächsten Boot sehen können, dass die alte Datei gelöscht und neue Datei erstellt, aber der Inhalt der neuen Datei ist nicht Komplett. Durch die Synchronisierung zu tun, stellen Sie sicher, dass die neue Datei vollständig an diesem Punkt so geschrieben wird, kann weitere Veränderungen tun (wie die alte Datei zu löschen), die an diesem Zustand abhängen.

Andere Tipps

fileOut.getFD().sync(); auf der finally-Klausel sein sollte, vor dem close().

sync() ist viel wichtiger als close() Berücksichtigung Haltbarkeit.

Also, jedes Mal wenn Sie auf ‚Fertig stellen‘ arbeiten an einer Datei sollten Sie es sync() bevor es close()ing.

Posix nicht garantiert werden, dass anhängige Schreibvorgänge auf die Festplatte geschrieben werden, wenn Sie eine close() erteilen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top