Работа с файловой системой в C++: полное руководство для начинающих

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

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

Начать курс

Работа с файловой системой в C++: от основ до продвинутых техник

Работа с файловой системой — одна из ключевых задач в любом серьёзном приложении на C++. Будь то чтение конфигурационных файлов, запись логов, обработка больших объёмов данных или управление проектами — умение правильно взаимодействовать с файлами и директориями необходимо каждому C++ разработчику. В этой статье мы разберём основные подходы к работе с файловой системой в C++, начиная от классических C-функций и заканчивая современным std::filesystem, появившимся в C++17.

Мы рассмотрим практические примеры, которые помогут вам не только понять теорию, но и сразу применить полученные знания в реальных проектах. Все примеры кода протестированы и готовы к использованию.

1. Основы работы с файлами: потоки ввода/вывода

Наиболее распространённый способ работы с файлами в C++ — использование библиотеки <fstream>. Она предоставляет три основных класса:

  • std::ifstream — для чтения из файла (input file stream);
  • std::ofstream — для записи в файл (output file stream);
  • std::fstream — для чтения и записи (file stream).

Чтение из файла

Для чтения данных из файла создайте объект std::ifstream и откройте файл. Самый простой способ прочитать файл построчно — использовать функцию std::getline:

#include <iostream>
#include <fstream>
#include <string>

int main() {
    std::ifstream inputFile("example.txt");
    if (!inputFile.is_open()) {
        std::cerr << "Ошибка открытия файла!" << std::endl;
        return 1;
    }

    std::string line;
    while (std::getline(inputFile, line)) {
        std::cout << line << std::endl;
    }

    inputFile.close();
    return 0;
}

Обратите внимание на проверку is_open() — это важная практика, которая предотвращает краш программы при отсутствии файла.

Запись в файл

Для записи данных используется std::ofstream. По умолчанию файл создаётся заново (режим trunc). Если нужно дописать данные в конец, используйте флаг std::ios::app:

#include <iostream>
#include <fstream>

int main() {
    std::ofstream outputFile("output.txt", std::ios::app);
    if (!outputFile.is_open()) {
        std::cerr << "Ошибка создания файла!" << std::endl;
        return 1;
    }

    outputFile << "Строка 1" << std::endl;
    outputFile << "Строка 2" << std::endl;
    outputFile << "Число: " << 42 << std::endl;

    outputFile.close();
    return 0;
}

Работа с бинарными файлами

Для бинарных данных используйте методы read() и write() с указанием размера блока:

#include <iostream>
#include <fstream>
#include <cstring>

struct Record {
    int id;
    char name[50];
    double value;
};

int main() {
    // Запись
    Record r = {1, "Тестовая запись", 3.14};
    std::ofstream binOut("data.bin", std::ios::binary);
    binOut.write(reinterpret_cast<const char*>(&r), sizeof(r));
    binOut.close();

    // Чтение
    Record r2;
    std::ifstream binIn("data.bin", std::ios::binary);
    binIn.read(reinterpret_cast<char*>(&r2), sizeof(r2));
    binIn.close();

    std::cout << "ID: " << r2.id << ", Name: " << r2.name
              << ", Value: " << r2.value << std::endl;
    return 0;
}

2. Современный подход: библиотека std::filesystem (C++17)

Начиная с C++17, в стандартную библиотеку была добавлена <filesystem>, которая значительно упрощает работу с файловой системой. Она предоставляет удобные функции для работы с путями, директориями и файлами.

Проверка существования файла и получение информации

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main() {
    fs::path filePath("example.txt");

    if (fs::exists(filePath)) {
        std::cout << "Файл существует" << std::endl;
        std::cout << "Размер: " << fs::file_size(filePath) << " байт" << std::endl;
        std::cout << "Расширение: " << filePath.extension() << std::endl;
    } else {
        std::cout << "Файл не найден" << std::endl;
    }

    return 0;
}

Работа с директориями

Создание, удаление и обход директорий — одни из самых частых операций. Вот как это делается с помощью std::filesystem:

#include <iostream>
#include <filesystem>
#include <vector>

namespace fs = std::filesystem;

int main() {
    // Создание директории
    fs::create_directory("my_folder");

    // Создание вложенных директорий
    fs::create_directories("my_folder/sub_folder/deep");

    // Обход всех файлов в директории
    std::cout << "Содержимое текущей директории:" << std::endl;
    for (const auto& entry : fs::directory_iterator(".")) {
        std::cout << (entry.is_directory() ? "[DIR] " : "[FILE] ")
                  << entry.path().filename() << std::endl;
    }

    // Рекурсивный обход
    std::cout << "\nРекурсивный обход:" << std::endl;
    for (const auto& entry : fs::recursive_directory_iterator("my_folder")) {
        std::cout << entry.path() << std::endl;
    }

    // Удаление директории (пустой)
    fs                

Блоги

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