1. Introducción
Hay muchísimos escenarios donde se necesitan operaciones de movimiento: mover archivos "descargados" desde una carpeta temporal a la carpeta de documentos, ordenar masivamente fotos, renombrar por una plantilla, procesar correo y logs. El sistema de archivos prefiere el orden — bueno, o al menos algo parecido. Y un buen desarrollador debe saber imponer ese orden.
Además, estas tareas suelen aparecer en entrevistas: "Escribe una utilidad que renombre todos los archivos añadiéndoles un número de versión", o "Crea un comando que mueva documentos obsoletos al archivo". Vamos a ver cómo se hace esto en C#.
Resumen de posibilidades
En .NET hay dos formas principales para mover y renombrar: usar métodos estáticos (File.Move, Directory.Move) o métodos de instancia (FileInfo.MoveTo, DirectoryInfo.MoveTo). Todos estos métodos, bajo el capó, hacen casi lo mismo — lo que cambia principalmente es la sintaxis.
¿Cómo "ve" .NET el movimiento y el renombrado?
¡Atención! Renombrar y mover son esencialmente la misma operación: un archivo o carpeta en distintos lugares del sistema de archivos se identifica por su ruta. Si la ruta cambia — se considera que el objeto "se movió" o "fue renombrado". Si solo cambias el nombre pero dejas el mismo directorio — es un renombrado. Si cambias toda la ruta — es un movimiento. Filosóficamente, como Schrödinger: el objeto está movido y renombrado si le das una ruta nueva con un nombre nuevo.
2. Mover y renombrar archivos: ejemplos
Vamos de lo simple a lo complejo y seguiremos con el ejemplo de nuestro mini gestor de archivos.
Método estático File.Move
Aquí tienes un ejemplo de cómo mover (o renombrar) un archivo:
// Movemos el archivo test1.txt a otra carpeta con un nombre nuevo
File.Move(@"C:\Temp\test1.txt", @"C:\Archive\test1_archived.txt");
Y si solo quieres renombrar el archivo en la misma carpeta:
// Simplemente cambiamos el nombre del archivo
File.Move(@"C:\Temp\test1.txt", @"C:\Temp\test_renamed.txt");
¡Esa es toda la magia! .NET simplemente "quita" una ruta y "asigna" otra al objeto, si ambas rutas son accesibles y no hay conflictos.
Método estático Directory.Move
Con carpetas — igual:
// Movemos la carpeta
Directory.Move(@"C:\Temp\OldFolder", @"C:\Temp\NewFolder");
Puedes tanto renombrar la carpeta (nuevo nombre en el mismo directorio) como moverla completamente a otro lugar.
3. Métodos de instancia: FileInfo.MoveTo y DirectoryInfo.MoveTo
Cuando ya tienes un objeto FileInfo o DirectoryInfo, puedes llamar al método MoveTo():
var fileInfo = new FileInfo(@"C:\Temp\test1.txt");
fileInfo.MoveTo(@"C:\Archive\test1_archived.txt");
// Carpetas:
var dirInfo = new DirectoryInfo(@"C:\Temp\OldFolder");
dirInfo.MoveTo(@"C:\Temp\NewFolder");
Aquí también: si la ruta nueva es el mismo directorio pero con otro nombre, ocurre un renombrado; si es otro directorio — un movimiento.
4. ¿Y si el archivo ya existe en el destino?
Aquí empiezan los matices que suelen "morder" en el peor momento.
File.Move
Si ya existe un archivo en la ruta de destino — se lanzará una excepción IOException, y tu código "fallará":
try
{
File.Move("data.txt", "archive\\data.txt");
}
catch (IOException ex)
{
Console.WriteLine("¡El archivo de destino ya existe! " + ex.Message);
}
FileInfo.MoveTo
La situación es la misma — IOException si el archivo de destino ya existe.
Directory.Move
Con carpetas la cosa es aún más estricta: si la carpeta destino ya existe — excepción. No puedes mover una carpeta a una ubicación que ya esté ocupada.
Moral: ¡Siempre comprueba si ya existe ese archivo o carpeta donde intentas escribir!
// Comprobamos tranquilamente si existe el archivo en la ruta destino
if (!File.Exists("archive\\data.txt"))
{
File.Move("data.txt", "archive\\data.txt");
}
else
{
Console.WriteLine("¡El archivo de destino ya existe!");
}
5. Matices útiles
Ejemplo de renombrado de carpeta
var oldDir = @"C:\Projects\OldReport";
var newDir = @"C:\Projects\NewReport";
// Comprobamos que la carpeta antigua exista y que la nueva no exista
if (Directory.Exists(oldDir) && !Directory.Exists(newDir))
{
Directory.Move(oldDir, newDir);
Console.WriteLine("Carpeta renombrada con éxito.");
}
else
{
Console.WriteLine("Error: la carpeta origen no se encontró o la nueva ya existe.");
}
Renombrado teniendo en cuenta el contenido anidado
Todo el contenido de la carpeta (subcarpetas, archivos) se moverá junto con ella sin comandos adicionales. Es cómodo: con un solo comando una carpeta con cualquier nivel de anidamiento aparece en la nueva ubicación.
Buenas prácticas y métodos útiles de la clase Path
Cuando renombres o muevas archivos, usa los métodos de la clase System.IO.Path para construir correctamente la nueva ruta o cambiar el nombre del archivo:
- Obtener el nombre de archivo sin extensión: Path.GetFileNameWithoutExtension(path)
- Cambiar solo la extensión: Path.ChangeExtension(path, ".bak")
- Construir una nueva ruta con otro nombre: Path.Combine(Path.GetDirectoryName(path), "newname.txt")
string oldPath = @"C:\Reports\2023_Final.docx";
string newName = "2023_Archive.docx";
string newPath = Path.Combine(Path.GetDirectoryName(oldPath)!, newName);
File.Move(oldPath, newPath);
6. Matices importantes y errores típicos
Permisos y bloqueo
Si no tienes permisos de escritura en alguna de las rutas — se lanzará la excepción UnauthorizedAccessException. De forma similar, si el archivo está siendo usado por otro proceso (por ejemplo, abierto en Word), obtendrás un error. Es un caso muy común.
Movimiento entre diferentes discos y volúmenes
En esencia, File.Move realiza una operación rápida de renombrado dentro de un mismo volumen/disco. Si intentas mover un archivo del disco C al disco D — .NET automáticamente hará una copia seguida de la eliminación del archivo origen. Si algo sale mal (por ejemplo, el disco destino se queda sin espacio), el archivo origen quedará en su lugar.
Dato interesante: casi todos los sistemas de archivos modernos soportan "renombrado/movimiento rápido" dentro del mismo volumen, y al mover entre volúmenes se hace copia + eliminación.
Mover carpetas enteras (Directory.Move)
No puedes mover una carpeta dentro de sí misma ni a una subcarpeta suya (por ejemplo, C:\Data a C:\Data\Archive) — eso provocará un error.
¿Cómo mover de forma segura?
Antes de cualquier movimiento, especialmente masivo, comprueba la existencia del origen (File.Exists, Directory.Exists) y la ausencia de conflicto en el destino. Y no olvides el try-catch: el sistema de archivos es caprichoso y puede tirar un error en el momento más inesperado.
GO TO FULL VERSION