Si la ubicación original y la nueva del archivo se encuentran en el mismo sistema de archivos, "mover" es conceptualmente idéntico a "cambiar el nombre".
#include <stdio.h>
int rename (const char *oldname, const char *newname)
La forma habitual de mover un archivo en C es usar rename(2), que a veces falla.
Si no puede usar la llamada al sistema de cambio de nombre (2) (por ejemplo, porque el origen y el destino están en diferentes sistemas de archivos), debe consultar el tamaño, el permiso y otros metadatos del archivo de origen con stat (2); copie el bucle de datos en read(2), write(2) (usando un búfer de varios kilobytes), open(2), close(2) y los metadatos usando chmod(2), chown(2), utime(2) . También puede interesarle copiar atributos usando getxattr(2), setxattr(2), listxattr(2). En algunos casos, también podría usar sendfile(2), como comenta David C. Rankin.
Y si el origen y el destino están en diferentes sistemas de archivos, no hay forma de hacer que el movimiento sea atómico y evitar las condiciones de carrera (por lo tanto, es preferible usar rename(2) cuando sea posible, porque es atómico según su página de manual). El archivo de origen siempre se puede modificar (mediante otro proceso) durante las operaciones de movimiento...
Entonces, una forma práctica de mover archivos es intentar primero hacer un cambio de nombre (2), y si eso falla con EXDEV
(cuando ruta antigua y nueva ruta no están en el mismo sistema de archivos montado), entonces necesita copiar bytes y metadatos. Varias bibliotecas proporcionan funciones que hacen eso, p. Qt QFile::renombrar.
Lea Programación avanzada de Linux - y vea syscalls(2) - para obtener más información (y también intente strace
unos mv
comando para entender lo que está haciendo). Ese libro se puede descargar libre y legalmente (por lo que podría encontrar varias copias en la Web).
El /bin/mv
El comando (ver mv(1)) es parte de GNU coreutils, que es software libre. Puede estudiar su código fuente o usar strace(1) para entender lo que hace ese comando (en términos de llamadas al sistema(2)). En algunos shells Unix de código abierto como sash o busybox, mv
podría ser un shell incorporado. Consulte también resolución_ruta(7) y global(7).
Hay casos de esquina sutiles (imagine otro proceso o pthread haciendo algunas operaciones de archivos en el mismo sistema de archivos, directorio o archivos). Lea algún libro de texto del sistema operativo para obtener más información.
Usar una combinación de snprintf(3), system(3), mv(1) podría ser complicado si el nombre del archivo contiene caracteres raros como tab o
o saltos de línea, o comienza con un -
inicial . Ver número de error(3).