ext4 / fsync Situation unklar in Android (Java)

Tim Brays Artikel "Sichern sicher" hat mich mit offenen Fragen verlassen. Heute ist es über einen Monat alt und ich habe kein Follow-up auf sie gesehen, also habe ich beschlossen, das Thema hier anzusprechen.

Ein Punkt des Artikels ist, dass FileDescriptor.sync () aufgerufen werden sollte, auf der sicheren Seite zu sein, wenn Sie FileOutputStream verwenden. Zuerst war ich sehr gereizt, denn ich habe nie einen Java-Code gesehen, der eine Synchronisierung während der 12 Jahre macht, die ich Java mache. Vor allem seit der Bewältigung von Dateien ist eine ziemlich grundlegende Sache. Auch die Standard-JavaDoc von FileOutputStream hat nie auf Synchronisierung (Java 1.0 – 6) angedeutet. Nach einigen Recherchen, dachte ich, ext4 kann tatsächlich das erste Mainstream-Dateisystem sein, das Synchronisierung erfordert. (Gibt es noch andere Dateisysteme, bei denen explizite Synchronisierung empfohlen wird?)

Ich schätze einige allgemeine Gedanken über die Angelegenheit, aber ich habe auch einige spezifische Fragen:

  1. Wann wird Android die Synchronisierung mit dem Dateisystem? Dies könnte periodisch sein und zusätzlich auf Lebenszyklusereignissen basieren (zB ein App-Prozess geht in den Hintergrund).
  2. Funktioniert FileDescriptor.sync () die Synchronisierung der Metadaten? Das ist das Synchronisieren des Verzeichnisses der geänderten Datei. Vergleich mit FileChannel.force ().
  3. Normalerweise schreibt man nicht direkt in das FileOutputStream. Hier ist meine Lösung (sind Sie einverstanden?):
     FileOutputStream fileOut = ctx.openFileOutput (Datei, Context.MODE_PRIVATE);
     BufferedOutputStream out = new BufferedOutputStream (fileOut);
     Versuchen {
         out.write (etwas);
         out.flush ();
         fileOut.getFD () sync ();
     } endlich {
         out.close ();
     }
    

  • Wie zu debuggen "com.android.okhttp"
  • Android Bottom White Streifen beim Ausfüllen von Webview Inhalt
  • Wie kann ich den Hintergrund machen? Aktivität kleiner beim Öffnen der Navigationsschublade?
  • Android: bestimmen Sie die Prozess-ID meiner App?
  • Android: Wird ein neuer Thread einfach aufhören, nachdem es seine Ausführung beendet hat?
  • Wie erstelle ich ein Objekt mit JNI?
  • Android View Kind hinzufügen
  • Tabelle mit variabler Spaltenbreite pro Zeile (ähnlich UICollectionView für iOS)
  • 2 Solutions collect form web for “ext4 / fsync Situation unklar in Android (Java)”

    Android wird die Synchronisierung ausführen, wenn es nötig ist – z. B. wenn der Bildschirm ausgeschaltet wird, das Gerät heruntergefahren wird usw. Wenn Sie nur einen "normalen" Betrieb betrachten, wird explizite Synchronisierung durch Anwendungen nie benötigt.

    Das Problem kommt, wenn der Benutzer den Akku aus dem Gerät zieht (oder einen starken Reset des Kernels), und Sie möchten sicherstellen, dass Sie keine Daten verlieren.

    Also das erste, was zu realisieren ist: das Problem ist, wenn die Macht plötzlich verloren geht, so dass ein sauberes Herunterfahren nicht passieren kann, und die Frage, was in der anhaltenden Speicherung an diesem Punkt passieren wird.

    Wenn Sie nur eine einzige unabhängige neue Datei schreiben, ist es nicht wichtig, was Sie tun. Der Benutzer hätte die Batterie gezogen, während du in der Mitte des Schreibens warst, genau bevor du anfing zu schreiben usw. Wenn du nicht synchronisierst, bedeutet das nur, dass es längere Zeit gibt, wann du fertig warst, während du die Batterie ziehst wird die Daten verlieren.

    Die große Sorge hier ist, wenn Sie eine Datei aktualisieren möchten. In diesem Fall, wenn Sie als nächstes die Datei lesen, die Sie entweder den vorherigen Inhalt oder den neuen Inhalt haben möchten. Du willst nichts auf halbem Weg schreiben oder die Daten verlieren.

    Dies geschieht oft, indem man die Daten in eine neue Datei schreibt und dann aus der alten Datei wechselt. Vor deiner Erwähnung wussten Sie, dass, sobald Sie fertig waren, eine Datei zu schreiben, weitere Operationen auf anderen Dateien nicht auf Festplatte gehen, bis die auf dieser Datei, so dass Sie sicher löschen könnte die vorherige Datei oder sonst tun Operationen, die von Ihrer neuen Datei abhängen vollständig geschrieben

    Doch jetzt, wenn Sie die neue Datei schreiben, dann löschen Sie die alte, und die Batterie wird gezogen, wenn Sie beim nächsten Booten Sie sehen, dass die alte Datei gelöscht und neue Datei erstellt wird, aber der Inhalt der neuen Datei ist nicht vollständig. Wenn Sie die Synchronisierung durchführen, stellen Sie sicher, dass die neue Datei an dieser Stelle vollständig geschrieben ist, so dass weitere Änderungen (wie das Löschen der alten Datei), die von diesem Zustand abhängen, durchgeführt werden können.

    fileOut.getFD().sync(); sollte auf der endgültigen Klausel sein, vor dem close() .

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

    Also, jedes Mal, wenn Sie 'beenden' arbeiten an einer Datei, die Sie sync() sollten sync() es vor close() es zu beenden.

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

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.