Boost.Filesystem для C++: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Boost.Filesystem для C++: Полное руководство по работе с файловой системой

Boost.Filesystem — это мощная и зрелая библиотека на C++, предоставляющая портативный (кроссплатформенный) интерфейс для выполнения операций с файловой системой. Она является частью коллекции библиотек Boost и, по сути, стала прототипом для стандартной библиотеки <filesystem> в C++17. Если вы работаете с C++11 или C++14 и вам нужен надежный, проверенный временем инструмент для работы с путями, файлами и директориями, Boost.Filesystem — это ваш выбор.

Зачем она нужна? Стандартный C++ долгое время не имел встроенных средств для таких простых задач, как проверка существования файла, создание директории или рекурсивный обход папок. Разработчикам приходилось использовать stat() на Linux или GetFileAttributes() на Windows, что делало код непереносимым. Boost.Filesystem решает эту проблему, предоставляя единый API, который работает одинаково на всех основных платформах. Библиотека инкапсулирует системные вызовы, обрабатывает кодировки путей (например, UTF-8 на Linux и UTF-16 на Windows) и предлагает удобные классы для работы с путями и итерации по директориям.

В этой статье мы подробно разберем установку библиотеки, основные классы и методы, а также приведем реальный практический пример, который вы сможете использовать в своих проектах. Мы сосредоточимся на версии Boost 1.84 (актуальной на момент написания), но примеры будут работать и с более старыми версиями.

Установка Boost.Filesystem

В отличие от языков с пакетными менеджерами (npm, pip), C++ требует компиляции библиотек. Boost.Filesystem — это header-only библиотека только для некоторых частей; для работы с файлами требуется скомпилированная библиотека (libboost_filesystem).

Установка через пакетный менеджер (рекомендуется)

Ubuntu/Debian (Linux):

sudo apt update
sudo apt install libboost-filesystem-dev

macOS (Homebrew):

brew install boost

Windows (vcpkg):

vcpkg install boost-filesystem

Сборка из исходников (если нет пакетного менеджера)

# Скачайте Boost с официального сайта
wget https://boostorg.jfrog.io/artifactory/main/release/1.84.0/source/boost_1_84_0.tar.gz
tar -xzf boost_1_84_0.tar.gz
cd boost_1_84_0

# Запустите bootstrap
./bootstrap.sh

# Соберите только библиотеку filesystem (экономит время)
./b2 --with-filesystem

# Установите (обычно в /usr/local)
sudo ./b2 install

Компиляция проекта с Boost.Filesystem

При компиляции необходимо указать путь к заголовочным файлам и линковаться с библиотекой:

g++ -std=c++11 -I/path/to/boost main.cpp -lboost_filesystem -lboost_system -o my_program

Быстрый старт: минимальный рабочий пример

Давайте напишем простую программу, которая проверяет, существует ли файл, и выводит его размер.

#include <iostream>
#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

int main() {
    // Путь к файлу
    fs::path file_path("example.txt");

    // Проверяем, существует ли файл
    if (fs::exists(file_path)) {
        // Получаем размер файла
        uintmax_t file_size = fs::file_size(file_path);
        std::cout << "Файл: " << file_path.filename() << std::endl;
        std::cout << "Размер: " << file_size << " байт" << std::endl;
    } else {
        std::cout << "Файл не найден." << std::endl;
    }

    return 0;
}

Этот код демонстрирует три ключевые возможности: создание объекта пути (fs::path), проверку существования файла (fs::exists) и получение его размера (fs::file_size).

Основные классы и методы Boost.Filesystem

Рассмотрим 8+ наиболее часто используемых компонентов библиотеки.

1. Класс boost::filesystem::path

Сигнатура: class path { ... };

Что делает: Представляет собой путь к файлу или директории в файловой системе. Обрабатывает разделители, кодировки и предоставляет удобные методы для манипуляции с частями пути.

Пример:

fs::path p("/home/user/docs/file.txt");
std::cout << "Полный путь: " << p << std::endl;
std::cout << "Родительская директория: " << p.parent_path() << std::endl;
std::cout << "Имя файла: " << p.filename() << std::endl;
std::cout << "Расширение: " << p.extension() << std::endl;
std::cout << "Стебель (имя без расширения): " << p.stem() << std::endl;

// Конкатенация путей
fs::path new_path = p.parent_path() / "new_file.txt";
std::cout << "Новый путь: " << new_path << std::endl;

2. Функция boost::filesystem::exists

Сигнатура: bool exists(const path& p);

Что делает: Проверяет, существует ли файл или директория по указанному пути.

Пример:

fs::path p("test.txt");
if (fs::exists(p)) {
    std::cout << "Файл существует." << std::endl;
} else {
    std::cout << "Файл не существует." << std::endl;
}

3. Функция boost::filesystem::is_directory

Сигнатура: bool is_directory(const path& p);

Что делает: Проверяет, является ли путь директорией.

Пример:

fs::path dir("my_folder");
if (fs::is_directory(dir)) {
    std::cout << "Это директория." << std::endl;
} else {
    std::cout << "Это не директория или она не существует." << std::endl;
}

4. Функция boost::filesystem::create_directory

Сигнатура: bool create_directory(const path& p);

Что делает: Создает новую директорию. Возвращает true, если директория была создана, и false, если она уже существует.

Пример:

fs::path new_dir("new_folder");
if (fs::create_directory(new_dir)) {
    std::cout << "Директория создана." << std::endl;
} else {
    std::cout << "Директория уже существует." << std::endl;
}

// Рекурсивное создание директорий
fs::create_directories("a/b/c/d");

5. Функция boost::filesystem::remove

Сигнатура: bool remove(const path& p);

Что делает: Удаляет файл или пустую директорию. Возвращает true в случае успеха.

Пример:

fs::path file_to_remove("old_file.txt");
if (fs::remove(file_to_remove)) {
    std::cout << "Файл удален." << std::endl;
} else {
    std::cout << "Не удалось удалить файл." << std::endl;
}

// Рекурсивное удаление (удаляет директорию и все её содержимое)
fs::remove_all("folder_to_delete");

6. Функция boost::filesystem::copy_file

Сигнатура: void copy_file(const path& from, const path& to); (и перегрузки с опциями)

Что делает: Копирует содержимое одного файла в другой. Существующий целевой файл будет перезаписан.

Пример:

fs::path source("source.txt");
fs::path dest("backup/source_copy.txt");
try {
    fs::copy_file(source, dest);
    std::cout << "Файл скопирован." << std::endl;
} catch (fs::filesystem_error& e) {
    std::cerr << "Ошибка копирования: " << e.what() << std::endl;
}

7. Функция boost::filesystem::rename

Сигнатура: void rename(const path& old_p, const path& new_p);

Что делает: Переименовывает или перемещает файл/директорию.

Пример:

fs::path old_name("temp.txt");
fs::path new_name("final.txt");
fs::rename(old_name, new_name);
std::cout << "Файл переименован." << std::endl;

8. Класс boost::filesystem::directory_iterator

Сигнатура: class directory_iterator { ... };

Что делает: Позволяет итерироваться по содержимому директории (только первый уровень).

Пример:

fs::path dir_path(".");
if (fs::is_directory(dir_path)) {
    for (fs::directory_iterator it(dir_path); it != fs::directory_iterator(); ++it) {
        std::cout << it->path().filename() << std::endl;
    }
}

9. Класс boost::filesystem::recursive_directory_iterator

Сигнатура: class recursive_directory_iterator { ... };

Что делает: Позволяет рекурсивно обходить все поддиректории.

Пример:

fs::path root(".");
for (fs::recursive_directory_iterator it(root); it != fs::recursive_directory_iterator(); ++it) {
    // Выводим только файлы (не директории)
    if (fs::is_regular_file(it->status())) {
        std::cout << it->path() << std::endl;
    }
}

10. Функция boost::filesystem::file_size

Сигнатура: uintmax_t file_size(const path& p);

Что делает: Возвращает размер файла в байтах.

Пример:

fs::path p("large_file.bin");
try {
    uintmax_t size = fs::file_size(p);
    std::cout << "Размер файла: " << size << " байт" << std::endl;
} catch (fs::filesystem_error& e) {
    std::cerr << "Ошибка: " << e.what() << std::endl;
}

Реальный практический пример: Утилита для очистки временных файлов

Представим, что нам нужно написать программу, которая находит все файлы с расширением .tmp в заданной директории (и поддиректориях), старше 7 дней, и удаляет их. Это классическая задача для системного администратора.

#include <iostream>
#include <vector>
#include <chrono>
#include <ctime>
#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

// Структура для хранения информации о файле
struct FileInfo {
    fs::path path;
    std::time_t last_write_time;
    uintmax_t size;
};

// Функция для поиска файлов по расширению и возрасту
std::vector<FileInfo> find_old_tmp_files(const fs::path& root_dir, int days_old) {
    std::vector<FileInfo> old_files;
    std::time_t now = std::time(nullptr);
    std::time_t cutoff_time = now - (days_old * 24 * 60 * 60); // 7 дней в секундах

    // Проверяем, существует ли корневая директория
    if (!fs::exists(root_dir) || !fs::is_directory(root_dir)) {
        std::cerr << "Ошибка: корневая директория не существует или не является директорией." << std::endl;
        return old_files;
    }

    // Рекурсивный обход
    for (fs::recursive_directory_iterator it(root_dir); it != fs::recursive_directory_iterator(); ++it) {
        try {
            // Пропускаем директории
            if (fs::is_directory(it->status())) {
                continue;
            }

            // Проверяем расширение
            if (it->path().extension() == ".tmp") {
                std::time_t last_write = fs::last                    

Рекомендаций