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

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

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

Начать курс

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

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

Основы работы с файлами: библиотека fstream

Библиотека fstream (<fstream>) предоставляет три основных класса для работы с файлами:

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

Чтение данных из файла

Рассмотрим простейший пример открытия и чтения текстового файла построчно:

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

int main() {
    std::ifstream inputFile("data.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(). Файл автоматически закроется при выходе из области видимости, но явный вызов close() считается хорошей практикой.

Запись данных в файл

Запись в файл выполняется аналогично выводу в консоль — с помощью оператора <<:

#include <fstream>

int main() {
    std::ofstream outputFile("output.txt");
    if (!outputFile) {
        std::cerr << "Не удалось создать файл!" << std::endl;
        return 1;
    }

    outputFile << "Строка 1" << std::endl;
    outputFile << "Строка 2" << std::endl;
    outputFile << 42 << std::endl; // числа записываются автоматически как текст

    outputFile.close();
    return 0;
}

По умолчанию ofstream перезаписывает файл. Чтобы добавить данные в конец, используйте флаг std::ios::app:

std::ofstream outputFile("log.txt", std::ios::app);

Бинарные файлы и произвольный доступ

Для работы с бинарными данными используйте флаг std::ios::binary. Методы read() и write() позволяют работать с блоками памяти:

#include <fstream>

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

int main() {
    // Запись структуры
    Record rec = {1, "Пример"};
    std::ofstream binOut("data.bin", std::ios::binary);
    binOut.write(reinterpret_cast<char*>(&rec), sizeof(rec));
    binOut.close();

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

    return 0;
}

Для позиционирования внутри файла используйте seekg() (для ввода) и seekp() (для вывода) с параметрами std::ios::beg, std::ios::cur или std::ios::end.

Современный C++: библиотека std::filesystem

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

Работа с путями

Класс std::filesystem::path — центральный элемент библиотеки. Он автоматически обрабатывает разделители путей в зависимости от операционной системы:

#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;

int main() {
    // Создание пути
    fs::path myPath = "C:/Users/User/Documents/file.txt";

    std::cout << "Корневой путь: " << myPath.root_path() << std::endl;
    std::cout << "Родительская директория: " << myPath.parent_path() << std::endl;
    std::cout << "Имя файла: " << myPath.filename() << std::endl;
    std::cout << "Расширение: " << myPath.extension() << std::endl;
    std::cout << "Стебель (имя без расширения): " << myPath.stem() << std::endl;

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

    return 0;
}

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

Библиотека позволяет легко проверить, существует ли файл, является ли он директорией, а также получить его размер и другие атрибуты:

#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;

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

    if (fs::exists(filePath)) {
        std::cout << "Файл существует." << std::endl;

        if (fs::is_regular_file(filePath)) {
            std::cout << "Это обычный файл." << std::endl;
            std::cout << "Размер: " << fs::file_size(filePath) << " байт" <                

Блоги

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