Считывание бинарного файла c. Работа с бинарными файлами. BinaryWriter и BinaryReader

Для работы с бинарными файлами предназначена пара классов BinaryWriter и BinaryReader . Эти классы позволяют читать и записывать данные в двоичном формате.

Основные метода класса BinaryWriter

    Flush() : очищает буфер, дописывая из него оставшиеся данные в файл

    Seek() : устанавливает позицию в потоке

    Write() : записывает данные в поток

Основные метода класса BinaryReader

    Close() : закрывает поток и освобождает ресурсы

    ReadBoolean() : считывает значение bool и перемещает указатель на один байт

    ReadByte() : считывает один байт и перемещает указатель на один байт

    ReadChar() : считывает значение char, то есть один символ, и перемещает указатель на столько байтов, сколько занимает символ в текущей кодировке

    ReadDecimal() : считывает значение decimal и перемещает указатель на 16 байт

    ReadDouble() : считывает значение double и перемещает указатель на 8 байт

    ReadInt16() : считывает значение short и перемещает указатель на 2 байта

    ReadInt32() : считывает значение int и перемещает указатель на 4 байта

    ReadInt64() : считывает значение long и перемещает указатель на 8 байт

    ReadSingle() : считывает значение float и перемещает указатель на 4 байта

    ReadString() : считывает значение string. Каждая строка предваряется значением длины строки, которое представляет 7-битное целое число

С чтением бинарных данных все просто: соответствующий метод считывает данные определенного типа и перемещает указатель на размер этого типа в байтах, например, значение типа int занимает 4 байта, поэтому BinaryReader считает 4 байта и переместит указать на эти 4 байта.

Посмотрим на реальной задаче применение этих классов. Попробуем с их помощью записывать и считывать из файла массив структур:

Struct State { public string name; public string capital; public int area; public double people; public State(string n, string c, int a, double p) { name = n; capital = c; people = p; area = a; } } class Program { static void Main(string args) { State states = new State; states = new State("Германия", "Берлин", 357168, 80.8); states = new State("Франция", "Париж", 640679, 64.7); string path= @"C:\SomeDir\states.dat"; try { // создаем объект BinaryWriter using (BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.OpenOrCreate))) { // записываем в файл значение каждого поля структуры foreach (State s in states) { writer.Write(s.name); writer.Write(s.capital); writer.Write(s.area); writer.Write(s.people); } } // создаем объект BinaryReader using (BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open))) { // пока не достигнут конец файла // считываем каждое значение из файла while (reader.PeekChar() > -1) { string name = reader.ReadString(); string capital = reader.ReadString(); int area = reader.ReadInt32(); double population = reader.ReadDouble(); Console.WriteLine("Страна: {0} столица: {1} площадь {2} кв. км численность населения: {3} млн. чел.", name, capital, area, population); } } } catch (Exception e) { Console.WriteLine(e.Message); } Console.ReadLine(); } }

Итак, у нас есть структура State с некоторым набором полей. В основной программе создаем массив структур и записываем с помощью BinaryWriter. Этот класс в качестве параметра в конструкторе принимает объект Stream, который создается вызовом File.Open(path, FileMode.OpenOrCreate) .

Затем в цикле пробегаемся по массиву структур и записываем каждое поле структуры в поток. В том порядке, в каком эти значения полей записываются, в том порядке они и будут размещаться в файле.

Затем считываем из записанного файла. Конструктор класса BinaryReader также в качестве параметра принимает объект потока, только в данном случае устанавливаем в качестве режима FileMode.Open: new BinaryReader(File.Open(path, FileMode.Open))

В цикле while считываем данные. Чтобы узнать окончание потока, вызываем метод PeekChar() . Этот метод считывает следующий символ и возвращает его числовое представление. Если символ отсутствует, то метод возвращает -1, что будет означать, что мы достигли конца файла.

В цикле последовательно считываем значения поле структур в том же порядке, в каком они записывались.

Таким образом, классы BinaryWriter и BinaryReader очень удобны для работы с бинарными файлами, особенно когда нам известна структура этих файлов. В то же время для хранения и считывания более комплексных объектов, например, объектов классов, лучше подходит другое решение - сериализация.

ДВОИЧНАЯ ЗАПИСЬ

(binary notation) Запись чисел только двумя символами. Символами, как правило, являются 0 и 1, которые называются двоичными разрядами (binary digits), или битами (bits). Биты обычно группируются по восемь символов, называемых байтами (bytes). Числа, записанные в двоичной форме, выглядят значительно длиннее, чем при десятичной записи. Например, двоичное число 1111 является эквивалентом записанного в десятичной форме числа 15. В двоичном числе колонки справа налево представляют собой "единицы", "двойки", "четверки", "восьмерки" и т.д. Двоичная используется в компьютерных расчетах по той причине, что цифровые компьютеры представляют числа в форме наличия (1) или отсутствия (0) электрического импульса.


Бизнес. Толковый словарь. - М.: "ИНФРА-М", Издательство "Весь Мир". Грэхэм Бетс, Барри Брайндли, С. Уильямс и др. Общая редакция: д.э.н. Осадчая И.М. . 1998 .

Смотреть что такое "ДВОИЧНАЯ ЗАПИСЬ" в других словарях:

    двоичная запись - — [Л.Г.Суменко. Англо русский словарь по информационным технологиям. М.: ГП ЦНИИС, 2003.] Тематики информационные технологии в целом EN binary notation … Справочник технического переводчика

    Система счисления (См. Счисление), построенная на позиционном принципе записи чисел, с основанием 2. В Д. с. с. используются только два знака цифры 0 и 1; при этом, как и во всякой позиционной системе, значение цифры зависит дополнительно … Большая советская энциклопедия

    Эта статья или раздел нуждается в переработке. Пожалуйста, улучшите статью в соответствии с правилами написания статей … Википедия

    - (decimal notation) Повседневная система записи чисел цифрами от 0 до 9. В десятичном числе место цифры, считая справа налево, показывает увеличение кратности числа 10. См. также: двоичная запись (binary notation). Бизнес. Толковый словарь. М.:… … Словарь бизнес-терминов

    - (RSA Signature Scheme with Appendix Probabilistic Signature Scheme) асимметричный алгоритм цифровой подписи. Основан на принципе кодирования PSS, предложенном в 1996 году авторами Mihir Bellare и Phillip Rogaway. Внесён в стандарт PKCS#1 v2.1… … Википедия

    - (bit) Аббревиатура понятия двоичный разряд. См.: двоичная запись (binary notation). Бизнес. Толковый словарь. М.: ИНФРА М, Издательство Весь Мир. Грэхэм Бетс, Барри Брайндли, С. Уильямс и др. Общая редакция: д.э.н. Осадчая И.М.. 1998. Бит … Словарь бизнес-терминов

    Калифорнийский автомобильный номер на Leet: T3h1337 (Teh Leet) Leet (1337) распространившийся в Интернете стиль употребления английского языка. Основные отличия замена латинских букв на похожие цифры и символы, имитация и … Википедия

    У этого термина существуют и другие значения, см. Nimrod (значения). Nimrod Nimrod (также NIMROD) компьютер для игры в ним. Имел режимы как для игры человека с компьютером, так и для игры компьютера с … Википедия

Файл имеет следующие характерные особенности :
  • имеет имя на диске, что дает возможность программам идентифицировать и работать с несколькими файлами;
  • длина файла ограничивается только емкостью диска.

Часто бывает необходимо ввести некоторые данные из файла или вывести результаты в файл . Например, бывает необходимо обрабатывать массивы, которые слишком велики, чтобы полностью разместиться в памяти.

Файлы делятся на текстовые и двоичные.

Текстовый файл – это файл , в котором каждый символ из используемого набора символов хранится в виде одного байта (кода, соответствующего символу). Текстовые файлы разбиваются на несколько строк с помощью специального символа "конец строки". Текстовый файл заканчивается специальным символом " конец файла ".

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

Особенностью языка С++ является отсутствие в нем структурированных файлов. Все файлы рассматриваются как неструктурированная последовательность байтов. При таком подходе понятие файла распространяется и на различные устройства.

В С++ существуют специальные средства ввода-вывода данных. Все операции ввода-вывода реализуются с помощью функций, которые находятся в библиотеке С++. Библиотека С++ поддерживает три уровня ввода-вывода:

  • потоковый ввод-вывод;
  • ввод-вывод нижнего уровня;
  • ввод-вывод для консоли и портов (зависит от ОС).

Поток – это абстрактное понятие, относящееся к любому переносу данных от источника к приемнику.

Функции библиотеки ввода-вывода языка С++, поддерживающие обмен данными с файлами на уровне потока, позволяют обрабатывать данные различных размеров и форматов, обеспечивая при этом буферизованный ввод и вывод . Таким образом, поток представляет собой этот файл вместе с предоставленными средствами буферизации.

Чтение данных из потока называется извлечением, вывод в поток – помещением (включением) .

Поток определяется как последовательность байтов и не зависит от конкретного устройства, с которым производится обмен ( оперативная память , файл на диске, клавиатура или принтер). Обмен с потоком для увеличения скорости передачи данных производится, как правило, через специальную область оперативной памятибуфер . Буфер накапливает байты, и фактическая передача данных выполняется после заполнения буфера ( рис. 19.1). При вводе это дает возможность исправить ошибки, если данные из буфера еще не отправлены в программу.


Рис. 19.1.

При работе с потоком можно:

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

Когда программа начинает выполняться, автоматически открываются пять потоков, из которых основными являются:

  • стандартный поток ввода (на него ссылаются, используя предопределенный указатель на поток stdin );
  • стандартный поток вывода (stdout );
  • стандартный поток вывода сообщений об ошибках (stderr ).

По умолчанию стандартному потоку ввода stdin ставится в соответствие клавиатура, а потокам stdout и stderr соответствует экран монитора.

В С++ операции с файлами можно осуществлять в двух режимах: форматированном и потоковом .

Рассмотрим основные функции для работы с файлами в форматированном режиме.

Функция открытия файла

Для работы с файлом в языке C++ необходима ссылка на файл . Для определения такой ссылки существует структура FILE , описанная в файле stdio.h . Данная структура содержит все необходимые поля для управления файлами, например: текущий указатель буфера, текущий счетчик байтов, базовый адрес буфера ввода-вывода, номер файла.

При открытии файла (потока) в программу возвращается указатель на поток (файловый указатель ), являющийся указателем на объект структурного типа FILE . Этот указатель идентифицирует поток во всех последующих операциях.

Например:

#include .............. FILE *fp;

Для открытия файла существует функция fopen , которая инициализирует файл .

Синтаксис :

fp=fopen(ИмяФайла, РежимОткрытия);

где fp – указатель на поток (файловый указатель );

ИмяФайла – указатель на строку символов, представляющую собой допустимое имя файла , в которое может входить спецификация файла (включает обозначение логического устройства, путь к файлу и собственно имя файла );

РежимОткрытия – указатель на строку режима открытия файла.

Например:

fp=fopen("t.txt","r");

Существуют несколько режимов открытия файлов.

Режимы открытия файлов
Режим Описание Начинается с...
r Открывает текстовый файл для чтения. Если файл не существует, то выдается ошибка при исполнении программы. начала
w Открывает текстовый файл для записи. Если файл не существует, то он создается. Если файл уже существует, то удаляется его содержимое, файл перезаписывается начала
a Открывает текстовый файл для добавления. Если файл не существует, то он создается. Если существует, то содержимое из него не удаляется. конца
r+ Открывает текстовый файл для чтения и записи. Изменить размер файла нельзя. Если файл не существует, то выдается ошибка при исполнении программы. начала
w+ Открывает текстовый файл для чтения и записи. Если файл не существует, то он создается. Если файл уже существует, то удаляется его содержимое, файл перезаписывается. начала
a+ Открывает текстовый файл для чтения и записи. Если файл не существует, то он создается. Если существует, то содержимое из него не удаляется. конца
rb Открывает двоичный файл для чтения. Если файл не существует, то выдается ошибка при исполнении программы. начала
wb Открывает двоичный файл для записи. Если файл не существует, то он создается. Если файл уже существует, то удаляется его содержимое, файл перезаписывается. начала
ab Открывает двоичный файл для добавления. Если файл не существует, то он создается. Если существует, то содержимое из него не удаляется. конца
r+b Открывает двоичный файл для чтения и записи. Изменить размер файла нельзя. Если файл не существует, то выдается ошибка при исполнении программы. начала
rb+
w+b Открывает двоичный файл для чтения и записи. Если файл не существует, то он создается. Если файл уже существует, то удаляется его содержимое, файл перезаписывается. начала
wb+
a+b Открывает двоичный файл для чтения и записи. Если файл не существует, то он создается. Если существует, то содержимое из него не удаляется. конца
ab+


Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: