cpp-renombrar-eliminar-archivos

How to Rename, Move, and Delete Files in C++

  • 3 min

File management in C++ involves renaming, moving, or deleting filesystem entries from our program.

In the previous article, we learned how to create and read files. But managing files involves more than just looking at their contents. Sometimes we need to perform maintenance tasks: changing names, moving files between folders, or deleting them.

In the old days (before C++17), this was a headache. We had to resort to inherited C functions (<cstdio>) that were clunky and varied between Windows and Linux.

Fortunately, C++17 introduced the <filesystem> library, which standardizes all these operations and makes them much safer and more powerful.

To use the examples in this article, you need a compiler compatible with C++17 or higher.

The std::filesystem Library

To get started, we need to include the library. For convenience, it’s very common to create an alias for the namespace, since std::filesystem is quite long to write.

#include <iostream>
#include <filesystem> // Required

namespace fs = std::filesystem; // Alias for less typing
Copied!

Now we can access all functions using fs::.

Renaming or Moving Files

The fs::rename function is used to change a file’s name and, when the system allows it, move it from one directory to another.

void renameFile() {
    fs::path source = "old.txt";
    fs::path destination = "new.txt";

    try {
        fs::rename(source, destination);
        std::cout << "File renamed successfully.\n";
    } 
    catch (fs::filesystem_error& e) {
        std::cerr << "Error: " << e.what() << "\n";
    }
}
Copied!

Caution: If the destination file already exists, the behavior may depend on the system and the type of path. If you don’t want to overwrite or run into weird errors, check fs::exists(destination) beforehand.

Moving to Another Folder

If you specify a different folder in the destination path, the file will be moved.

// Moves the file to the 'backup' subfolder
fs::rename("data.txt", "backup/data_2023.txt"); 
Copied!

The backup folder must already exist, otherwise it will throw an error.

Deleting Files

We have two main functions for deleting files:

  1. fs::remove(path): Deletes a single file or an empty directory. Returns true if something was deleted, false if it didn’t exist.
  2. fs::remove_all(path): Deletes a file or a directory and all its contents recursively.
void deleteFile() {
    fs::path file = "trash.tmp";

    // Safe way: check first
    if (fs::exists(file)) {
        fs::remove(file);
        std::cout << "File deleted.\n";
    } else {
        std::cout << "The file does not exist.\n";
    }
}
Copied!

Delete operations in C++ are permanent. Files do not go to the recycle bin. They are permanently erased from the disk.

Error Handling

Working with the filesystem is error-prone (the file is missing, you lack permissions, the disk is full).

std::filesystem has two ways to report errors:

  1. Exceptions (Default): As we saw in the first example, if something fails, it throws fs::filesystem_error.
  2. Error Code (No-throw): If you prefer not to use try-catch, you can pass an error variable as the last argument.
std::error_code ec;
fs::rename("a.txt", "b.txt", ec); // Does not throw exception

if (ec) {
    std::cout << "Failure: " << ec.message() << "\n";
}
Copied!

The Old C Method

You might encounter old code that doesn’t use <filesystem>. In that case, you’ll see functions from the C library <cstdio>.

  • std::rename(const char* old, const char* new)
  • std::remove(const char* path)

These functions work with C-style strings (char*), so if you use std::string you’ll need to use .c_str().

#include <cstdio>

// Old style (NOT RECOMMENDED in modern C++)
if (std::remove("file.txt") != 0) {
    perror("Error deleting file");
}
Copied!

The problem with these functions is that error handling is much poorer, and they don’t handle paths with special characters or unicode well across different operating systems (Windows vs Linux).