Question

L'article de Tim Bray "Enregistrement des données en toute sécurité" m'a laissé avec des questions ouvertes. Aujourd'hui, il est plus d'un mois et je n'ai pas vu suivi, donc j'ai décidé d'aborder le sujet ici.

Un point de l'article est que FileDescriptor.sync () doit être appelée à être sur le côté sécurité lorsque vous utilisez FileOutputStream. Au début, j'étais très irrité, parce que je ne l'ai vu tout code Java faire une synchronisation au cours des 12 années que je fais Java. D'autant plus que faire face à des fichiers est une chose assez basique. En outre, le niveau de JavaDoc FileOutputStream jamais fait allusion à la synchronisation (Java 1.0 à 6) -. Après quelques recherches, je me suis dit ext4 peut effectivement être le premier système de fichiers grand public nécessitant la synchronisation. (Y at-il d'autres systèmes de fichiers où la synchronisation explicite est conseillé?)

Je comprends quelques réflexions générales sur la question, mais j'ai aussi quelques questions spécifiques:

  1. Quand Android ne la synchronisation avec le système de fichiers? Cela pourrait être périodique et en plus en fonction des événements de cycle de vie (par exemple le processus d'une application va à l'arrière-plan).
  2. Est-ce que prendre soin FileDescriptor.sync () de la synchronisation des méta-données? Cela est synchronisez le répertoire du fichier modifié. Comparer à FileChannel.force ().
  3. En général, on ne pas écrire directement dans le FileOutputStream. Voici ma solution (trouvez-vous d'accord?):
    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();
    }
    
Était-ce utile?

La solution

Android fera la synchronisation quand il doit -. Par exemple lorsque l'écran est éteint, éteindre l'appareil, etc. Si vous cherchez simplement à un fonctionnement « normal », la synchronisation explicite des applications est jamais nécessaire

Le problème vient lorsque l'utilisateur tire la batterie de leur appareil (ou fait un redémarrage à froid du noyau), et que vous voulez vous assurer que vous ne perdez pas de données.

La première chose à réaliser:. La question est quand le pouvoir est soudainement perdu, donc un arrêt propre ne peut pas se produire, et la question de ce qui va se passer dans le stockage persistant à ce point

Si vous écrivez un seul nouveau fichier indépendant, il ne compte pas vraiment ce que vous faites. L'utilisateur aurait pu tiré la batterie pendant que vous étiez au milieu de l'écriture, juste avant de commencer à écrire, etc. Si vous ne se synchronisent pas, cela signifie juste il y a quelque temps à partir de quand vous écrivez ce qui fait pendant tirant la batterie perdrez les données.

La grande préoccupation ici est quand vous voulez mettre à jour un fichier. Dans ce cas, lorsque vous lisez ensuite le fichier que vous voulez avoir soit précédent contenu, ou nouveau Contenu. Vous ne voulez pas obtenir quelque chose à mi-chemin écrit, ou perdre les données.

Ceci est souvent fait en écrivant les données dans un nouveau fichier, puis passer à celle de l'ancien fichier. Avant de vous Ext4 saviez que, une fois que vous aviez fini d'écrire un fichier, d'autres opérations sur d'autres fichiers ne pas aller sur le disque jusqu'à ce que ceux sur ce fichier, vous pouvez supprimer en toute sécurité le fichier précédent ou autrement faire des opérations qui dépendent de votre nouveau fichier étant entièrement écrit.

Mais maintenant, si vous écrivez le nouveau fichier, puis supprimez l'ancien, et la batterie est tiré, lors de votre prochaine démarrage, vous pouvez voir que l'ancien fichier est supprimé et nouveau fichier créé, mais le contenu du nouveau fichier n'est pas Achevée. En faisant la synchronisation, assurez-vous que le nouveau fichier est complètement écrit à ce moment-là ne peut donc faire d'autres changements (tels que la suppression de l'ancien fichier) qui dépendent de cet état.

Autres conseils

fileOut.getFD().sync(); devrait être mis sur la clause enfin, avant la close().

sync() est beaucoup plus important que close() compte tenu de la durabilité.

Alors, chaque fois que vous voulez « fini » travailler sur un fichier que vous devez sync() avant close()ing il.

posix ne garantit pas que les dernières écritures seront écrites sur le disque lorsque vous émettez une close().

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top