Similar presentations:
Работа с двоичными файлами
1.
Работа сдвоичными
файлами
2.
Двоичные (бинарные) файлыДвоичные файлы хранят данные в виде набора
байт. Работа с двоичными файлами не похожа на
работу с текстовыми (<< и >> не используются)
Здесь также используются классы ifstream и
ofstream из библиотеки <fstream>
Для работы с файлом в двоичном режиме нужно
указать флаг ios::binary
3.
Режимы открытия файлов• ifstream fin(nameF, ios::in | ios::binary);
• ofstream fout(nameF,ios::app |ios::binary);
• fstream finout(nameF, ios::in | ios::out | ios::binary);
4.
Запись строки в двоичный файл• Для записи в двоичный файл используется метод write,
принимающий указатель на массив байт (char*) и количество
записываемых байт. Пример записи строки:
string s = "Hello, world!";
ofstream file("text.dat", ios::binary);
if (file.is_open()) {
file.write(s.c_str(), s.length() + 1);
file.close();
}
5.
Чтение строки из двоичного файла• Для чтения из двоичного файла используется read,
принимающий указатель на массив байт (char*) и количество
считываемых байт. Пример чтения строки:
ifstream file("text.dat", ios::binary);
if (file.is_open()) {
char s[15];
file.read(s, 15);
cout << s;
}
6.
Запись в двоичные файлы• Для записи нестроковых данных в двоичные файлы их
необходимо интерпретировать как массив байт. Для этого
используется преобразование reinterpret_cast
int a = 5;
char* data = reinterpret_cast<char*>(&a);
Теперь data - указатель на массив четырех байт, в
котором записано число 5
7.
Запись в двоичные файлыПример записи массива целых чисел
int arr[5] = { 1, 2, 3, 4, 5 };
ofstream file("text.dat", ios::binary);
if (file.is_open()) {
for (int i = 0; i < 5; i++) {
file.write(reinterpret_cast<char*>(&arr[i]),
sizeof(int));
}
file.close();
}
8.
Запись в двоичные файлыПо умолчанию при открытии на запись файл
создается, если его не было, или перезаписывается,
если такой файл уже существует
Чтобы не перезаписывать файл, а дописать в его
конец, нужно дополнить режим открытия файла
флагом app (от слова append). Такой режим
позволяет только дописывать в конец
9.
Запись в двоичные файлыТеперь при каждом запуске данные будут
дописываться в конец
int arr[5] = { 1, 2, 3, 4, 5 };
ofstream file("text.dat", ios::binary | ios::app);
if (file.is_open()) {
for (int i = 0; i < 5; i++) {
file.write(reinterpret_cast<char*>(&arr[i]),
sizeof(int));
}
file.close();
}
10.
Файловый указатель для чтенияПример. Дан бинарный файл, содержащий целые
числа типа int. Считать все числа
ifstream file("text.dat", ios::binary);
int value;
if (file.is_open()) {
while (!file.eof()) {
file.read(reinterpret_cast<char*>(&value),
sizeof(int));
cout << value << " ";
}
}
11.
Файловый указатель для чтенияПример. Дан бинарный файл, содержащий целые
числа типа int. Считать все числа (вариант 2)
12.
Файловый указатель• В отличие от текстового режима, в бинарном режиме можно
управлять, куда записывать и откуда считывать.
• Бинарный режим предоставляет произвольный доступ к
данным (можно сразу обратиться к любому байту, не считывая
предыдущие)
• Такое управление осуществляется через файловый
указатель
13.
Файловый указатель для чтенияПусть file - бинарный файл ifstream
● file.is_open() - проверяет, был ли файл успешно открыт.
Возвращает true/false
● file.close() - закрывает файл
● file.eof() - проверить, был ли достигнут конец файла
● file.get() - считать один байт
● file.peek() - получить следующий байт (но не считывать его)
● file.tellg() - получает текущую позицию указателя
● file.seekg(pos) - перемещает файловый указатель
● file.seekg(offset, origin) - перемещает файловый указатель
относительно позиции origin
14.
Файловый указатель для чтенияseekg(0, ios::end) - перейти к концу файла
seekg(-4, ios::cur) - сместиться на 4 байта влево от
текущего значения
seekg(8, ios::beg) - перейти на 8-ой байт с начала
файла
seekg(-4, ios::end) - перейти на 4-ой байт с конца
файла
15.
Файловый указатель для чтенияПример. Дан бинарный файл, содержащий целые
числа типа int. Считать последнее число
file.open("text.dat", ios::binary);
int intSize = sizeof(int);
if (file.is_open()) {
file.seekg(-intSize, ios::end);
int value;
file.read(reinterpret_cast<char*>(&value), intSize);
cout << value << " ";
file.close();
}
16.
Файловый указатель для записиПусть file - бинарный файл ofstream
● file.is_open() - проверяет, был ли файл успешно открыт.
Возвращает true/false
● file.close() - закрывает файл
● file.tellp() - получает текущую позицию указателя
● file.seekp(pos) - перемещает файловый указатель
● file.seekp(offset, origin) - перемещает файловый указатель
относительно позиции origin
17.
Файловый указатель для записиПример. Дан бинарный файл, содержащий целые
числа типа int. Заменить пятое число на 255
ofstream file("text.dat", ios::binary | ios::ate | ios::in);
int intSize = sizeof(int);
int value = 255;
if (file.is_open()) {
file.seekp(4 * intSize, ios::beg);
file.write(reinterpret_cast<char*>(&value), sizeof(int));
file.close();
}
18.
Запись в двоичные файлы• Режим ios::app не позволяет двигать файловый указатель.
Единственный способ открыть файл без перезаписи и
сохранить произвольный доступ - режим ios::ate (at the end).
Он также устанавливает указатель на конец файла при открытии.
Но такой режим подразумевает, что мы будем читать данные,
поэтому работает только вместе с режимом ios::in
19.
Чтение и запись в двоичные файлыИногда требуется одновременно читать из файла и
писать в него. Для этого существует тип fstream,
который включает в себя возможности и функции из
ifstream и ofstream. Для такого файла создаются 2
файловых указателя: “читающий” и “пишущий”
Для fstream требуется явно указывать, хотим ли мы
читать файл или записывать в него
20.
Чтение и запись в двоичные файлыОткрытие файла сразу на чтение и запись:
fstream file("text.dat", ios::binary | ios::in | ios::ate | ios::out);
Описание указанных режимов:
● ios::ate | ios::out - открыть на запись без перезаписи
● ios::in - открыть на чтение
● ios::binary - открыть в бинарном режиме
21.
Чтение и запись в двоичные файлы• Пример: дан двоичный файл, содержащий целые числа типа int.
Считать первое число и заменить им последнее число
fstream file("text.dat", ios::binary | ios::in |
ios::ate | ios::out);
• int intSize = sizeof(int); int value;
if (file.is_open()) {
file.seekg(0);
• file.read(reinterpret_cast<char*>(&value), intSize);
• file.seekp(-intSize, ios::end);
file.write(reinterpret_cast<char*>(&value), intSize);
file.close();
• }
22.
Запись структур в двоичный файлПреимущество двоичного режима - можно свободно
записывать сложные типы, например, структуры. C++
сам разберется, как именно записать данные
Рассмотрим примеры со структурой точки Point
struct Point {
double x, y;
};
23.
Запись структур в двоичный файлЗапись структуры в файл:
Point point; point.x = 2.5; point.y = 3.1415;
ofstream file("text.dat", ios::binary);
if (file.is_open()) {
file.write(reinterpret_cast<char*>(&point),
sizeof(Point));
file.close();
}
24.
Чтение структур из двоичного файлаЧтение структуры из файла:
Point point;
ifstream file("text.dat", ios::binary);
if (file.is_open()) {
file.read(reinterpret_cast<char*>(&point),
sizeof(Point));
cout << point.x << " " << point.y;
file.close();
}