Mientras no mueva el archivo a través de los bordes del sistema de archivos, la operación debe ser segura. Esto se debe al mecanismo, cómo se realiza realmente el "movimiento".
Si tiene mv
un archivo en el mismo sistema de archivos, el archivo no se toca realmente, sino que solo se modifica la entrada del sistema de archivos.
$ mv foo bar
en realidad hace algo como
$ ln foo bar
$ rm foo
Esto crearía un enlace rígido (una segunda entrada de directorio) para el archivo (en realidad el inodo señalado por la entrada del sistema de archivos) foo
nombrado bar
y eliminaría la foo
entrada. Como ahora al eliminar foo
, hay una segunda entrada del sistema de archivos que apunta al foo
inodo de '', eliminar la entrada anterior foo
no elimina realmente ningún bloque que pertenezca al inodo.
De todos modos, su programa se agregaría al archivo, ya que su identificador de archivo abierto apunta al inodo del archivo, no a la entrada del sistema de archivos.
Nota: Si su programa cierra y vuelve a abrir el archivo entre escrituras, ¡terminaría teniendo un nuevo archivo creado con la entrada anterior del sistema de archivos!
Movimientos cruzados del sistema de archivos:
Si mueve el archivo a través de los bordes del sistema de archivos, las cosas se ponen feas. En este caso, no puede garantizar que su archivo se mantenga constante, ya mv
que en realidad
- crear un nuevo archivo en el sistema de archivos de destino
- copie el contenido del archivo antiguo al archivo nuevo
- eliminar el archivo antiguo
o
$ cp /path/to/foo /path/to/bar
$ rm /path/to/foo
resp.
$ touch /path/to/bar
$ cat < /path/to/foo > /path/to/bar
$ rm /path/to/foo
Dependiendo de si la copia llega al final del archivo durante la escritura de su aplicación, podría suceder que solo tenga la mitad de una línea en el nuevo archivo.
Además, si su aplicación no cierra y vuelve a abrir el archivo anterior, continuaría escribiendo en el archivo anterior, incluso si parece haber sido eliminado: el núcleo sabe qué archivos están abiertos y, aunque eliminaría la entrada del sistema de archivos, no eliminará el inodo del archivo antiguo y los bloques asociados hasta que su aplicación cierre su identificador de archivo abierto.
rename()
llamada al sistema. Entonces, la versión original demv
realmente llamólink()
para crear el enlace duro, seguido deunlink()
eliminar el nombre original.rename()
fue agregado en FreeBSD, para implementar esto atómicamente en el kernel.