2012-08-05 5 views
15

Esta pregunta creo que es lo suficientemente técnica para S/O, y probablemente también orientada a la programación para Android. Estoy intrigado sobre cómo se manejan los archivos en Android (o en Java o Linux, según corresponda), ya que hice algo con mi nuevo teléfono inteligente y tenía curiosidad por saber cómo sucedió.¿Por qué puedo mover con éxito un archivo en Linux mientras se está escribiendo?

Estaba transfiriendo un archivo de mi computadora portátil a mi teléfono Android, a través de Bluetooth. Vi el nuevo archivo en el explorador de archivos, supuse que se había transferido por completo, y lo moví de /sdcard/bluetooth a /sdcard/torrents. Después de hacerlo, me di cuenta de que, de hecho, seguía siendo transferido. Para mi sorpresa, se completó con éxito, se confirmó con un ícono de notificación en el teléfono y con una verificación manual de MD5 en ambos lados. En la mayoría de los sistemas, el movimiento del archivo habría causado un bloqueo.

¿Cuál es el motivo de esta transferencia exitosa? Soy consciente de que, en general, la ruta del archivo está separada de la ubicación del archivo en el sistema de archivos (en este caso, una tarjeta SD). Me imagino que la aplicación Bluetooth ha abierto un identificador para el archivo, y cuando hice el movimiento del archivo, se actualizó una tabla de 'archivos abiertos' con una nueva ruta. ¿Es esta característica generalmente cierta de cualquier sistema Linux? ¿Podría hacer un mv en un archivo que se está escribiendo y esperar que la copia, en su nueva ubicación, sea correcta?

+0

archivos ¿Por qué se mueven entre dos sistemas de archivos diferentes causan un accidente, para empezar? Los archivos en sí son kludges de datos binarios; el sistema de archivos solo representa cómo se almacena, representa y elimina esa acumulación de datos. – Makoto

+1

No se esperaría que mover un archivo en sí mismo causara un bloqueo, pero usar 'mv' en un archivo _mientras todavía se está escribiendo en_ probablemente lo haría (ya que, en general, un sistema que escribe en un archivo debería poder suponer el archivo permanece en la misma ubicación desde la apertura de escritura hasta el cierre de escritura). Estoy tratando de entender si este último caso es válido para todos los sistemas Linux (o Java, o Android). ¡Puntos adicionales de explorador/brownie para cualquiera que pueda explicar por qué esto tiene éxito! – halfer

Respuesta

31

Al mover un archivo dentro del mismo sistema de ficheros, el propio archivo (el i-nodo ) no se mueve en absoluto. Lo único que cambia son las entradas de directorio en ese sistema de archivos. (La llamada al sistema invocada por mv en este caso es rename(2) - verificar que la página de información y restricciones adicionales.)

Cuando un proceso abre un archivo, el nombre del archivo se pasa al sistema operativo para indicar qué archivo se entiende, pero la El descriptor de archivo que recibe no está vinculado a ese nombre en absoluto (no puede recuperar un nombre de archivo) – está vinculado al inodo.
Dado que el inodo permanece inalterado cuando se cambia el nombre de un archivo (dentro del mismo sistema de archivos), los procesos que lo tienen abierto pueden seguir leyéndolo y escribiéndolo – nada cambió para ellos, su descriptor de archivo sigue siendo válido y apunta hacia la derecha datos.

Lo mismo si elimina un archivo. Los procesos pueden seguir leyéndolos y escribiéndolos aunque el archivo ya no se pueda acceder a través de ninguna entrada de directorio. (Esto puede llevar a situaciones confusas donde df informa que su disco está lleno, pero du informa que está utilizando mucho menos espacio que los informes df.Los bloques asignados a los archivos eliminados que aún están abiertos no se liberarán hasta que esos procesos cierren su descriptor de archivo.)

Si el mv mueve el archivo a través de sistemas de archivos, entonces el comportamiento es diferente ya que los inodos son específicos de cada sistema de archivos. En ese caso, mv realmente copiará los datos, creando un nuevo inodo (y entrada de directorio) en el sistema de archivos de destino. Cuando finaliza la copia, el archivo anterior se desvincula y se elimina si no hay filehandles abiertos en él, como se indicó anteriormente.
En su caso, si hubiera cruzado un límite del sistema de archivos, tendría un archivo parcial en el destino. Y su proceso de carga está escribiendo felizmente en un archivo eliminado al que no puede acceder fácilmente, posiblemente llenando ese sistema de archivos, hasta que termine la carga y en qué punto se eliminará el inodo.

Algunas funciones en Unix & Linux que podría resultar de interés:

+0

Gran respuesta, gracias Mat. Sí, estaba moviendo el archivo dentro del único sistema de archivos. Me he desarrollado en sistemas tipo Unix por algunos años, pero no he encontrado esta habilidad antes; Hubiera esperado que hubiera alterado el proceso de escritura. Cosas muy inteligentes! – halfer

Cuestiones relacionadas