2011-10-29 25 views
5

He escrito una aplicación para Android que guarda (potencialmente) archivos de gran tamaño en la tarjeta SD. Ocasionalmente obtengo una IOException durante la operación de escritura que hace que el archivo se quede en estado corrupto. Sobre la base de la respuesta a esta pregunta: ¿¿Cómo guardar de forma segura un archivo en el disco en Android?

Question: How to safely write to a file?

la estrategia que debe utilizar es crear un archivo temporal y luego copiar este archivo una vez que la escritura se ha completado. Mis preguntas son:

1) ¿Es este el método más seguro para Android? (Por ejemplo, ¿puede copiar archivos en la tarjeta sd de Android y si es así la operación atómica?)

2) En un sistema integrado con recursos limitados (espacio en disco), ¿alguien sabe de otra estrategia para escribir de forma segura en un disco? (En lugar de crear dos archivos de gran tamaño)

Gracias

+0

Lo siento, he entendido mal su pregunta. Eliminé mi respuesta. –

Respuesta

10

La forma típica para crear de forma segura un archivo en la mayoría de plataformas razonables (Linux/Android es uno de ellos) es la creación de un archivo temporal y luego de cambio de nombre el archivo, como se menciona en la pregunta & respuestas a las que se ha vinculado. Tenga en cuenta el énfasis en cambiar el nombre; cambiar el nombre de un archivo es generalmente una operación atómica dentro del mismo sistema de archivos, copiando uno no es. Además, este método solo requiere suficiente espacio para una sola copia de los datos.

Por lo tanto, crea un archivo en el directorio de destino usando un nombre temporal y luego usa File.renameTo() para darle un nombre propio. Al usar una convención de nomenclatura estándar para los archivos temporales, siempre puede encontrarlos y eliminarlos, incluso si su aplicación termina inesperadamente debido a, p. un dispositivo apagado

Si usted es realmente paranoico, es posible que desee insertar un par de llamadas a FileDescriptor.sync() o equivalente ...

EDIT:

Por cierto, usted no menciona qué tipo de IOException su están recibiendo y si has rastreado su causa. Si se debe a un espacio insuficiente, bien, pero si estamos hablando de una tarjeta SD defectuosa, entonces no existe tal cosa como "seguro" en este caso.

EDIT 2:

Con el fin de comprobar el espacio libre disponible, se puede crear un objeto de File para el directorio de destino (es decir, el directorio en el archivo va a terminar) y llamar a File.getFreeSpace(). Tenga en cuenta que este control no ofrece ninguna garantía; aún así puede terminar sin suficiente espacio si, por ejemplo, otro proceso escribe datos en el medio.

+0

Gracias por la respuesta clara. Renombrar tiene mucho sentido, me había perdido eso en la otra pregunta. – brif

+0

Renombrar definitivamente suena como la respuesta. Sin embargo, me preguntaba si puede verificar si tiene suficiente espacio libre en la SD para el archivo que está preparando para escribir. – Jeff

+0

@Jeff: puede llamar a ['File.getFreeSpace()'] (http://developer.android.com/reference/java/io/File.html#getFreeSpace%28%29) para evitar los casos más obvios de espacio insuficiente. – thkala

0

No sé si lo copiaría, pero el cambio de nombre del archivo temporal es típico. Si obtiene una excepción durante la escritura, simplemente elimine el archivo temporal.

3

Sé que es demasiado tarde para responder, pero ayudará a cualquiera que se encuentre con esto a encontrarlo útil.

Necesita usar AtomicFile.

El siguiente fragmento de código puede ayudar.

private void writeFile(File file, byte[] data) { 
    file.mkdirs(); 
    try { 
     AtomicFile aFile = new AtomicFile(file); 
     FileOutputStream fos = aFile.startWrite(); 
     fos.write(data); 
     aFile.finishWrite(fos); 
    } catch (IOException ioe) { 
     Log.e(TAG, "Cannot write file " + file.getPath()); 
    } 
} 
Cuestiones relacionadas