La gestión de archivos en C++ consiste en renombrar, mover o eliminar entradas del sistema de archivos desde nuestro programa.
En el artículo anterior aprendimos a crear y leer archivos. Pero gestionar archivos implica más que solo mirar su contenido. A veces necesitamos hacer labores de mantenimiento: cambiar nombres, mover archivos de carpeta o eliminarlos.
Antiguamente (antes de C++17), esto era un dolor de cabeza. Teníamos que recurrir a funciones heredadas de C (<cstdio>) que eran toscas y variaban entre Windows y Linux.
Por suerte, C++17 introdujo la librería <filesystem>, que estandariza todas estas operaciones y las hace mucho más seguras y potentes.
Para usar los ejemplos de este artículo necesitas un compilador compatible con C++17 o superior.
La librería std::filesystem
Para empezar, necesitamos incluir la librería. Por comodidad, es muy habitual crear un alias para el namespace, ya que std::filesystem es muy largo de escribir.
#include <iostream>
#include <filesystem> // Necesario
namespace fs = std::filesystem; // Alias para escribir menos
Ahora podemos acceder a todas las funciones usando fs::.
Renombrar o mover archivos
La función fs::rename sirve para cambiar el nombre de un archivo y, cuando el sistema lo permite, moverlo de un directorio a otro.
void renombrarArchivo() {
fs::path origen = "viejo.txt";
fs::path destino = "nuevo.txt";
try {
fs::rename(origen, destino);
std::cout << "Archivo renombrado con exito.\n";
}
catch (fs::filesystem_error& e) {
std::cerr << "Error: " << e.what() << "\n";
}
}
Cuidado: Si el archivo destino ya existe, el comportamiento puede depender del sistema y del tipo de ruta. Si no quieres sobrescribir ni encontrarte errores raros, comprueba antes fs::exists(destino).
Mover a otra carpeta
Si en la ruta de destino especificamos otra carpeta, el archivo se moverá.
// Mueve el archivo a la subcarpeta 'backup'
fs::rename("datos.txt", "backup/datos_2023.txt");
La carpeta backup debe existir previamente, o lanzará un error.
Eliminar archivos
Para borrar archivos tenemos dos funciones principales:
fs::remove(path): Borra un único archivo o un directorio vacío. Devuelvetruesi se borró algo,falsesi no existía.fs::remove_all(path): Borra un archivo o un directorio y todo su contenido de forma recursiva.
void borrarArchivo() {
fs::path archivo = "basura.tmp";
// Forma segura: comprobar antes
if (fs::exists(archivo)) {
fs::remove(archivo);
std::cout << "Archivo eliminado.\n";
} else {
std::cout << "El archivo no existe.\n";
}
}
Las funciones de borrado en C++ son definitivas. Los archivos no van a la papelera de reciclaje. Se eliminan del disco permanentemente.
Gestión de errores
Trabajar con el sistema de archivos es propenso a errores (el archivo no está, no tienes permisos, el disco está lleno).
std::filesystem tiene dos formas de reportar errores:
- Excepciones (Por defecto): Como vimos en el primer ejemplo, si algo falla lanza
fs::filesystem_error. - Código de Error (No-throw): Si prefieres no usar
try-catch, puedes pasar una variable de error como último argumento.
std::error_code ec;
fs::rename("a.txt", "b.txt", ec); // No lanza excepción
if (ec) {
std::cout << "Fallo: " << ec.message() << "\n";
}
El método antiguo de C
Es posible que te encuentres código antiguo que no usa <filesystem>. En ese caso, verás las funciones de la librería de C <cstdio>.
std::rename(const char* old, const char* new)std::remove(const char* path)
Estas funciones trabajan con cadenas de estilo C (char*), por lo que si usas std::string tendrás que usar .c_str().
#include <cstdio>
// Estilo antiguo (NO RECOMENDADO en C++ moderno)
if (std::remove("archivo.txt") != 0) {
perror("Error borrando archivo");
}
El problema de estas funciones es que el manejo de errores es mucho más pobre y no gestionan bien las rutas con caracteres especiales o unicode en diferentes sistemas operativos (Windows vs Linux).