0Pricing
C++ Academy · Урок

Двоичный ввод-вывод файлов

Читайте и записывайте необработанные байты

«Двоичный ввод-вывод файлов» — бесплатный урок C++ Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Текстовый и двоичный режимы

Текстовый режим записывает удобочитаемые символы; двоичный режим записывает необработанные байты объектов в точности так, как они представлены в памяти. Открывайте файл с помощью std::ios::binary.

#include <iostream>
#include <fstream>

int main() {
    int value = 12345;
    std::ofstream out("v.bin", std::ios::binary);
    out.write(reinterpret_cast<const char*>(&value), sizeof(value));
    std::cout << "wrote " << sizeof(value) << " bytes\n";
    return 0;
}

write принимает байты

write(ptr, n) выводит n необработанных байт из ptr. Адрес объекта преобразуется к типу const char*.

#include <iostream>
#include <fstream>

int main() {
    double d = 3.14;
    std::ofstream out("d.bin", std::ios::binary);
    out.write(reinterpret_cast<const char*>(&d), sizeof(d));
    out.close();
    std::cout << "saved a double\n";
    return 0;
}

read восстанавливает байты

read(ptr, n) загружает n байт в объект по адресу ptr, обращая результат двоичной записи.

#include <iostream>
#include <fstream>

int main() {
    int original = 777;
    std::ofstream("i.bin", std::ios::binary).write(reinterpret_cast<const char*>(&original), sizeof(original));
    int loaded = 0;
    std::ifstream in("i.bin", std::ios::binary);
    in.read(reinterpret_cast<char*>(&loaded), sizeof(loaded));
    std::cout << loaded << '\n';
    return 0;
}

Запись структуры POD

Структуры простых данных (без указателей, с полями фиксированного размера) можно выгрузить и загрузить обратно как единый блок байтов.

#include <iostream>
#include <fstream>

struct Record { int id; double balance; };

int main() {
    Record r{1, 99.5};
    std::ofstream out("rec.bin", std::ios::binary);
    out.write(reinterpret_cast<const char*>(&r), sizeof(r));
    std::cout << "struct saved\n";
    return 0;
}

Чтение структуры обратно

Чтение восстанавливает всю структуру за один вызов read.

#include <iostream>
#include <fstream>

struct Record { int id; double balance; };

int main() {
    Record w{42, 250.0};
    std::ofstream("r2.bin", std::ios::binary).write(reinterpret_cast<const char*>(&w), sizeof(w));
    Record r{};
    std::ifstream in("r2.bin", std::ios::binary);
    in.read(reinterpret_cast<char*>(&r), sizeof(r));
    std::cout << r.id << ' ' << r.balance << '\n';
    return 0;
}

Запись массива

Весь массив можно записать за один вызов, передав его общий размер в байтах.

#include <iostream>
#include <fstream>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    std::ofstream out("arr.bin", std::ios::binary);
    out.write(reinterpret_cast<const char*>(arr), sizeof(arr));
    std::cout << "wrote " << sizeof(arr) << " bytes\n";
    return 0;
}

Чтение массива обратно

Считайте то же количество байт в массив такого же размера.

#include <iostream>
#include <fstream>

int main() {
    int src[5] = {10, 20, 30, 40, 50};
    std::ofstream("a2.bin", std::ios::binary).write(reinterpret_cast<const char*>(src), sizeof(src));
    int dst[5] = {};
    std::ifstream in("a2.bin", std::ios::binary);
    in.read(reinterpret_cast<char*>(dst), sizeof(dst));
    for (int x : dst) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

Поиск позиций

seekg (чтение) и операция записи перемещают позицию чтения или записи, обеспечивая произвольный доступ к файлу.

#include <iostream>
#include <fstream>

int main() {
    int data[3] = {100, 200, 300};
    std::ofstream("seek.bin", std::ios::binary).write(reinterpret_cast<const char*>(data), sizeof(data));
    std::ifstream in("seek.bin", std::ios::binary);
    in.seekg(sizeof(int)); // skip to second int
    int second; in.read(reinterpret_cast<char*>(&second), sizeof(second));
    std::cout << second << '\n';
    return 0;
}

Получение позиции

tellg и позиция записи сообщают текущую позицию; это полезно для определения размера файла или смещений.

#include <iostream>
#include <fstream>

int main() {
    int data[4] = {1, 2, 3, 4};
    std::ofstream("tell.bin", std::ios::binary).write(reinterpret_cast<const char*>(data), sizeof(data));
    std::ifstream in("tell.bin", std::ios::binary);
    in.seekg(0, std::ios::end);
    std::cout << "file size: " << in.tellg() << " bytes\n";
    return 0;
}

Почему нельзя использовать указатели

Никогда не выгружайте в двоичном виде объекты, содержащие указатели или std::string: Вы сохраните адрес указателя, а не данные, на которые он указывает. Вместо этого сериализуйте содержимое.

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

int main() {
    std::string s = "hello";
    std::ofstream out("str.bin", std::ios::binary);
    std::size_t len = s.size();
    out.write(reinterpret_cast<const char*>(&len), sizeof(len));
    out.write(s.data(), len); // write the chars, not the object
    std::cout << "serialized " << len << " chars\n";
    return 0;
}

Ограничения переносимости

Двоичная раскладка зависит от порядка байтов и размеров типов. Файлы, записанные на одной платформе, могут неправильно читаться на другой, поэтому для обмена определяйте фиксированный формат.

#include <iostream>
#include <cstdint>

int main() {
    std::int32_t fixed = 1; // fixed-width type for portability
    std::cout << "sizeof int32_t = " << sizeof(fixed) << '\n';
    return 0;
}

Быстрая проверка

Проверьте, насколько хорошо Вы понимаете двоичный ввод-вывод.

Итоги

Вы изучили двоичный ввод-вывод файлов:

  • открывайте файл с помощью std::ios::binary; используйте write/read с reinterpret_cast<char*>
  • seekg/seekp и tellg/tellp обеспечивают произвольный доступ
  • никогда не выгружайте указатели или строки напрямую; сериализуйте их содержимое и учитывайте порядок байтов

Далее Вы научитесь проверять состояние потока и обрабатывать ошибки.

Часто задаваемые вопросы

Урок «Двоичный ввод-вывод файлов» бесплатный?

Да — полный текст урока «Двоичный ввод-вывод файлов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «Двоичный ввод-вывод файлов»?

Читайте и записывайте необработанные байты Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Двоичный ввод-вывод файлов»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Чтение файлов с ifstream
  2. Запись файлов с ofstream
  3. Двоичный ввод-вывод файлов
  4. Обработка ошибок и состояние
← Назад к C++ Academy