Pregunta

El artículo de Tim Bray "Almacenamiento de datos de forma segura" me dejó con preguntas abiertas. Hoy en día, es más de un mes de edad y no he visto ninguna de seguimiento sobre el mismo, por lo que decidí abordar el tema aquí.

Un punto del artículo es que FileDescriptor.sync () debe ser llamado para estar en el lado seguro cuando se utiliza FileOutputStream. Al principio, yo estaba muy irritado, porque nunca he visto ningún código de Java haciendo una sincronización durante los 12 años que hago Java. Sobre todo porque para hacer frente a los archivos es una cosa bastante básico. También, el JavaDoc estándar de FileOutputStream nunca se hizo alusión a la sincronización (Java 1.0 - 6). Después de algunas investigaciones, pensé ext4 puede ser en realidad el primer sistema de archivo de la corriente principal que requiere la sincronización. (¿Hay otros sistemas de archivos en el que se recomienda la sincronización explícita?)

Me apreciar algunas ideas generales sobre la materia, pero también tengo algunas preguntas específicas:

  1. Cuando se androide hacer la sincronización con el sistema de archivos? Esto podría ser periódica y, además, sobre la base de los eventos del ciclo de vida (por ejemplo, el proceso de una aplicación pasa a un segundo plano).
  2. ¿El FileDescriptor.sync () toma el cuidado de la sincronización de los metadatos? Que se sincroniza el directorio del archivo cambiado. Comparar a FileChannel.force ().
  3. Por lo general, uno no escribe directamente en el FileOutputStream. Aquí está mi solución (¿estás de acuerdo?):
    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();
    }
    
¿Fue útil?

Solución

Android va a hacer la sincronización cuando se necesita -. Como por ejemplo cuando se apague la pantalla, apagar el dispositivo, etc Si usted está buscando en el funcionamiento "normal", no se necesita sincronización explícita de aplicaciones

El problema viene cuando el usuario tira de la batería de su dispositivo (o hace un restablecimiento completo del núcleo), y desea asegurarse de que no pierda ningún dato.

Así que lo primero que se da cuenta:. El problema es cuando se pierde repentinamente el poder, por lo que un cierre limpio no puede suceder, y la cuestión de lo que va a ocurrir en el almacenamiento persistente en ese punto

Si se acaba de escribir una sola nuevo archivo independiente, que en realidad no importa lo que hagas. El usuario podría haber tirado de la batería mientras estaban en el medio de la escritura, justo antes de empezar a escribir, etc. Si no se sincronizan, sólo significa que hay algo de tiempo desde el momento en que escribimos hace durante el cual extrae la batería perderán los datos.

La gran preocupación aquí es cuando se quiere actualizar un archivo. En ese caso, la próxima vez que lea el archivo que desea tener o bien anterior contenido, o nueva contenido. Usted no quiere conseguir algo a medio camino escrito, o perder los datos.

Esto se suele hacer escribiendo los datos en un nuevo archivo, y luego cambiar a que desde el archivo antiguo. Antes de ext4 que sabía que, una vez que había terminado de escribir un archivo, más operaciones en otros archivos no irían en el disco hasta los que están en ese archivo, por lo que podría eliminar el archivo anterior o de lo contrario hacer operaciones que dependen de su nuevo archivo siendo totalmente por escrito.

Sin embargo, ahora si se escribe el nuevo archivo, a continuación, elimine el antiguo, y la batería se tira, la próxima vez que arranque puede ver que el archivo antiguo se elimina y el nuevo archivo creado, pero el contenido del nuevo archivo no es completar. Al hacer la sincronización, se asegura que el nuevo archivo está escrito completamente en ese momento por lo que puede hacer más cambios (tales como la eliminación del archivo de edad) que dependen de ese estado.

Otros consejos

fileOut.getFD().sync(); debe estar en la cláusula por último, antes de la close().

sync() es mucho más importante que close() teniendo en cuenta la durabilidad.

Por lo tanto, cada vez que quieren 'acabado' trabajando en un archivo que debe sync() antes close()ing él.

POSIX no garantiza que las escrituras pendientes se escriben en el disco cuando se emite un close().

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top