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

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

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

Начать курс

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

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

1. Основы работы с файлами через fstream

Классы ifstream (ввод из файла), ofstream (вывод в файл) и fstream (ввод/вывод) являются базовыми инструментами для работы с текстовыми и бинарными файлами. Они находятся в заголовочном файле <fstream>.

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

Чтобы прочитать данные из файла, создайте объект ifstream и откройте файл. Убедитесь, что файл существует, иначе поток будет в состоянии ошибки.

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

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

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

    file.close();
    return 0;
}

Запись в файл

Для записи используйте ofstream. Если файл не существует, он будет создан. Если существует, содержимое будет перезаписано (если не указан флаг std::ios::app).

#include <fstream>

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

    file << "Hello, world!\n";
    file << "C++ файловая система\n";

    file.close();
    return 0;
}

Добавление данных в конец файла

Используйте флаг std::ios::app (append), чтобы дописывать данные в конец, не удаляя предыдущие.

std::ofstream file("log.txt", std::ios::app);
file << "Новая запись\n";
file.close();

2. Работа с директориями и файловой системой (C++17)

Начиная с C++17, стандартная библиотека включает заголовок <filesystem>, который предоставляет удобный и кроссплатформенный интерфейс для работы с файловой системой. Чтобы использовать его, добавьте флаг компиляции -std=c++17 (или выше) и подключите <filesystem>.

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

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

int main() {
    fs::path p = "example.txt";
    
    if (fs::exists(p)) {
        std::cout << "Файл существует\n";
        std::cout << "Размер: " << fs::file_size(p) << " байт\n";
    } else {
        std::cout << "Файл не найден\n";
    }
    return 0;
}

Создание и удаление директорий

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

int main() {
    // Создание одной директории
    if (fs::create_directory("my_folder")) {
        std::cout << "Папка создана\n";
    }

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

    // Удаление пустой директории
    fs::remove("my_folder");

    // Удаление директории со всем содержимым (осторожно!)
    // fs::remove_all("a");

    return 0;
}

Перебор содержимого директории

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

int main() {
    std::string path = ".";
    for (const auto& entry : fs::directory_iterator(path)) {
        if (entry.is_regular_file()) {
            std::cout << "Файл: " << entry.path().filename() << "\n";
        } else if (entry.is_directory()) {
            std::cout << "Папка: " << entry.path().filename() << "\n";
        }
    }
    return 0;
}

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

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

Запись структуры в бинарный файл

#include <fstream>

struct Record {
    int id;
    double value;
};

int main() {
    Record r = {1, 3.14};

    std::ofstream file("data.bin", std::ios::binary);
    if (file.is_open()) {
        file.write(reinterpret_cast<char*>(&r), sizeof(r));
        file.close();
    }
    return 0;
}

Чтение структуры из бинарного файла

#include <fstream>
#include <iostream>

struct Record {
    int id;
    double value;
};

int main() {
    Record r;
    std::ifstream file("data.bin", std::ios::binary);
    if (file.is_open()) {
        file.read(reinterpret_cast<char*>(&r), sizeof(r));
        std::cout << "ID: " << r.id << ", Value: " << r.value << "\n";
        file.close();
    }
    return 0;
}

4. Продвинутые возможности std::filesystem

Библиотека filesystem предлагает и другие полезные функции: