Двоичный ввод-вывод файлов
Читайте и записывайте необработанные байты
«Двоичный ввод-вывод файлов» — бесплатный урок 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 — локальная установка не требуется.
Все уроки этого курса
- Чтение файлов с ifstream
- Запись файлов с ofstream
- Двоичный ввод-вывод файлов
- Обработка ошибок и состояние