cpp-renombrar-eliminar-archivos

Cómo renombrar, mover y eliminar archivos en C++

  • 3 min

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
Copied!

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";
    }
}
Copied!

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"); 
Copied!

La carpeta backup debe existir previamente, o lanzará un error.

Eliminar archivos

Para borrar archivos tenemos dos funciones principales:

  1. fs::remove(path): Borra un único archivo o un directorio vacío. Devuelve true si se borró algo, false si no existía.
  2. 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";
    }
}
Copied!

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:

  1. Excepciones (Por defecto): Como vimos en el primer ejemplo, si algo falla lanza fs::filesystem_error.
  2. 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";
}
Copied!

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");
}
Copied!

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).