Как создать бинарный файл в c

Бинарные файлы

Т екстовые файлы хранят данные в виде текста (sic!). Это значит, что если, например, мы записываем целое число 12345678 в файл, то записывается 8 символов, а это 8 байт данных, несмотря на то, что число помещается в целый тип. Кроме того, вывод и ввод данных является форматированным, то есть каждый раз, когда мы считываем число из файла или записываем в файл происходит трансформация числа в строку или обратно. Это затратные операции, которых можно избежать.

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

Выполните программу и посмотрите содержимое файла output.bin. Число, которое ввёл пользователь записывается в файл непосредственно в бинарном виде. Можете открыть файл в любом редакторе, поддерживающем представление в шестнадцатеричном виде (Total Commander, Far) и убедиться в этом.

Запись в файл осуществляется с помощью функции

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

Запись в бинарный файл объекта похожа на его отображение: берутся данные из оперативной памяти и пишутся как есть. Для считывания используется функция fread

Функция возвращает число удачно прочитанных элементов, которые помещаются по адресу ptr. Всего считывается count элементов по size байт. Давайте теперь считаем наше число обратно в переменную.

fseek

Одной из важных функций для работы с бинарными файлами является функция fseek

Эта функция устанавливает указатель позиции, ассоциированный с потоком, на новое положение. Индикатор позиции указывает, на каком месте в файле мы остановились. Когда мы открываем файл, позиция равна 0. Каждый раз, записывая байт данных, указатель позиции сдвигается на единицу вперёд.
fseek принимает в качестве аргументов указатель на поток и сдвиг в offset байт относительно origin. origin может принимать три значения

  • SEEK_SET — начало файла
  • SEEK_CUR — текущее положение файла
  • SEEK_END — конец файла. К сожалению, стандартом не определено, что такое конец файла, поэтому полагаться на эту функцию нельзя.

В случае удачной работы функция возвращает 0.

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

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

В си определён специальный тип fpos_t, который используется для хранения позиции индикатора позиции в файле.
Функция

используется для того, чтобы назначить переменной pos текущее положение. Функция

используется для перевода указателя в позицию, которая хранится в переменной pos. Обе функции в случае удачного завершения возвращают ноль.

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

Рассмотрим пример: пользователь вводит числа. Первые 4 байта файла: целое, которое обозначает, сколько чисел было введено. После того, как пользователь прекращает вводить числа, мы перемещаемся в начало файла и записываем туда число введённых элементов.

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

Примеры

1. Имеется бинарный файл размером 10*sizeof(int) байт. Пользователь вводит номер ячейки, после чего в неё записывает число. После каждой операции выводятся все числа. Сначала пытаемся открыть файл в режиме чтения и записи. Если это не удаётся, то пробуем создать файл, если удаётся создать файл, то повторяем попытку открыть файл для чтения и записи.

2. Пишем слова в бинарный файл. Формат такой — сначало число букв, потом само слово без нулевого символа. Ели длина слова равна нулю, то больше слов нет. Сначала запрашиваем слова у пользователя, потом считываем обратно.

3. Задача — считать данные из текстового файла и записать их в бинарный. Для решения зачи создадим функцию обёртку. Она будет принимать имя файла, режим доступа, функцию, которую необходимо выполнить, если файл был удачно открыт и аргументы этой функции. Так как аргументов может быть много и они могут быть разного типа, то их можно передавать в качестве указателя на структуру. После выполнения функции файл закрывается. Таким образом, нет необходимости думать об освобождении ресурсов.

4. Функция saveInt32Array позволяет сохранить массив типа int32_t в файл. Обратная ей loadInt32Array считывает массив обратно. Функция loadInt32Array сначала инициализирует переданный ей массив, поэтому мы должны передавать указатель на указатель; кроме того, она записывает считанный размер массива в переданный параметр size, из-за чего он передаётся как указатель.

5. Создание таблицы поиска. Для ускорения работы программы вместо вычисления функции можно произвести сначала вычисление значений функции на интервале с определённой точностью, после чего брать значения уже из таблицы. Программа сначала производит табулирование функции с заданными параметрами и сохраняет его в файл, затем подгружает предвычисленный массив, который уже используется для определения значений. В этой программе все функции возвращают переменную типа Result, которая хранит номер ошибки. Если функция отработала без проблем, то она возвращает Ok (0).

6. У нас имеются две структуры. Первая PersonKey хранит логин, пароль, id пользователя и поле offset. Вторая структура PersonInfo хранит имя и фамилию пользователя и его возраст. Первые структуры записываются в бинарный файл keys.bin, вторые структуры в бинарный файл values.bin. Поле offset определяет положение соответствующей информации о пользователе во втором файле. Таким образом, получив PersonKey из первого файла, по полю offset можно извлечь из второго файла связанную с данным ключом информацию.

Зачем так делать? Это выгодно в том случае, если структура PersonInfo имеет большой размер. Извлекать массив маленьких структур из файла не накладно, а когда нам понадобится большая структура, её можно извлечь по уже известному адресу в файле.

email

Всё ещё не понятно? – пиши вопросы на ящик

Создание бинарного файла

Создание бинарного дерево из бинарного файла
struct Bin < string name; string city; int players; int score; >; void.

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

Создание бинарного файла
Доброго времени суток. Покажите пожалуйста пример бинарного файла. Как его создать, как в него.

Сообщение от Wayrow
Сообщение от oleg-m1973
Лучший ответСообщение было отмечено Wayrow как решение

Решение

Сообщение от Wayrow
Сообщение от Wayrow
Сообщение от oleg-m1973

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

Создание бинарного файла под Linux
Это код, по которому идет проверка(test.c) #include &lt;unistd.h&gt; #include &lt;myfunc.h&gt; #include.

Быстрое создание бинарного файла заданного размера
Собственно, вопрос в теме. Как быстро выделить память под файл? Можно, конечно, методично записать.

Чтение нескольких структур и одной переменной из бинарного файла. Формат файла имеется
Формат файла состоит из 3 структур и одной переменной. Подробное описание формата во вложении.

Создание бинарного файла
Как в пхп создать бинарный файл записать в него бинарный код? спасибо!

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

Перед изучением данной темы рекомендуется ознакомиться со следующими темами:

Содержание

  • 1. Класс BinaryWriter . Назначение
  • 2. Взаимодействие класса BinaryWriter с потоками опорных хранилищ
  • 3. Конструкторы класса BinaryWriter . Создание экземпляра
  • 4. Основные методы класса BinaryWriter
    • 4.1. Метод Write() — много перегруженных реализаций
      • 4.1.1. Запись одиночных значений. Перегруженный метод Write() . Пример
      • 4.1.2. Запись байтовых массивов byte[] в поток. Пример
      • 4.1.3. Запись символьных массивов char[] в поток. Пример

      Поиск на других ресурсах:

      1. Класс BinaryWriter . Назначение

      Класс BinaryWriter предназначен для записи данных в двоичном (бинарном) формате. Запись данных может осуществляться в файлы, сеть, изолированное хранилище, память и т.п. Во время записи строк существует возможность указания нужной кодировки. По умолчанию установлена кодировка UTF-8.
      Класс реализован в пространстве имен System.IO . Для того, чтобы использовать возможности этого класса нужно добавить строку

      Класс BinaryWriter записывает данные, которые представлены:

      • примитивными типами: int , float , double и другими;
      • строками типа string в указанной кодировке.
      2. Взаимодействие класса BinaryWriter с потоками опорных хранилищ

      Класс BinaryWriter (а также BinaryReader ) относится к адаптерам потоков. Это означает следующее. Чтобы получить доступ к файлу, сети или памяти, нужно использовать промежуточный класс опорного хранилища ( FileStream , MemoryStream , NetworkStream и т.д.).
      На рисунке отображено взаимодействие класса BinaryWriter с файловым хранилищем, которому соответствует класс FileStream .

      Рисунок. Взаимодействие класса BinaryWriter с файлом через класс FileStream

      3. Конструкторы класса BinaryWriter . Создание экземпляра

      Класс BinaryWriter имеет несколько конструкторов, наиболее распространенными из которых следующие:

      • output – ссылка на абстрактный класс Stream , являющийся вершиной иерархии классов ввода-вывода;
      • encoding – система кодировки (Unicode, UTF32, UTF8 или другая). По умолчанию установлена система кодировки UTF8.

      Пример. Для того, чтобы создать экземпляр класса BinaryWriter и связать его с файлом «abc.bin» нужно выполнить приблизительно следующий код.

      Как видно из примера, при создании потоков используется синтаксис с использованием ключевого слова using() . Это освобождает от необходимости закрывать потоки методом Close() , поскольку при таком подходе очистка ресурсов происходит автоматически.

      4. Основные методы класса BinaryWriter
      4.1. Метод Write() — много перегруженных реализаций

      Главный метод класса BinaryWriter — метод Write() . Этот метод позволяет записывать в поток данные всех примитивных (стандартных) типов.

      Метод имеет 20 перегруженных реализаций, основные из которых приведены ниже.

      4.1.1. Запись одиночных значений. Перегруженный метод Write() . Пример

      Чтобы записать одиночные значения используются методы Write() , которые имеют следующую общую форму

      здесь value – значение одного из стандартных (примитивных) типовв, которое нужно записать в поток.

      Пример.

      В примере в файл «data.bin» записываются данные разных типов с помощью метода Write() . Затем эти данные считываются с целью контроля.

      Результат выполнения программы

      4.1.2. Запись байтовых массивов byte[] в поток. Пример

      Запись байт массивов типа byte[] полезен, когда в поток нужно записывать массивы стандартных типов (например, массивы int[] , double[] , decimal[] и т.д.). Для конвертирования из стандартных типов в тип byte[] удобно использовать возможности класса BitConverter .

      • buffer – участок памяти, из которого будут записываться данные в поток побайтно;
      • index – позиция (индекс) начала в массиве buffer , с которой будет происходить запись в поток;
      • count – количество байт, которые нужно записать в поток.

      Пример. В примере, с помощью метода Write() в файл «array.dat» записывается массив чисел типа double[] . Затем этот массив считывается и выводится на экран для сверки.

      Результат выполнения программы

      4.1.3. Запись символьных массивов char[] в поток. Пример

      Для записи строк символов в виде массива char[] используются две следующие реализации метода Write() :

      • chars – массив символов, который нужно записать в поток;
      • index — позиция первого символа в массиве chars , начиная с которой нужно записать данные;
      • count — количество символов, которые нужно прочитать из массива chars и записать в поток.

      Пример. В примере записывается строка типа string в файловый поток в виде символьного массива char[] .

      Результат выполнения программы

      4.2. Метод Seek() . Пример

      Метод Seek() устанавливает позицию в текущем потоке. Общая форма метода следующая:

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

      Значение origin есть перечислением и имеет тип

      Значения из перечисления могут быть следующими:

      • SeekOrigin.Begin — начальная точка отсчета устанавливается на начало потока (файла);
      • SeekOrigin.End — начальная точка отсчета устанавливается в конец потока (файла);
      • SeekOrigin.Current — определяется текущая позиция в потоке (файле).

      Пример. В примере продемонстрированы следующие операции:

      • запись чисел в файл;
      • перезапись ранее записанных чисел;
      • дописывание числа в конец файла.

      Результат выполнения программы

      4.3. Метод Flush() . Пример

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

      Как создать бинарный файл в c

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

      BinaryWriter

      Для создания объекта BinaryWriter можно применять ряд конструкторов. Возьмем наиболее простую:

      в его конструктор передается объект Stream (обычно это объект FileStream).

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

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

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

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

      Write() : записывает данные в поток. В качестве параметра этот метод может принимать значения примитивных данных:

      Либо можно передать массивы типов byte и char

      При записи массива дополнительно можно указать, с кого элемента массива надо выполнять запись, а также число записываемых элементов массива:

      Write(byte[], int, int)

      Write(char[], int, int)

      Рассмотрим простейшую запись бинарного файла:

      Здесь в файл person.dat записываются два значения: строка «Tom» и число 37. Для создание объекта применяется вызов new BinaryWriter(File.Open(path, FileMode.OpenOrCreate))

      Подобным образом можно сохранять более сложные данные. Например, сохраним в файл массив объектов:

      В данном случае последовательно сохраняем в файл people.dat данные объектов Person из массива people.

      BinaryReader

      Для создания объекта BinaryReader можно применять ряд конструкторов. Возьмем наиболее простую версию:

      в его конструктор также передается объект Stream (также обычно это объект FileStream).

      Основные методы класса 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 байта.

      Например, выше в примере с BinaryWriter в файл person.dat записывалась строка и число. Считаем их с помощью BinaryReader:

      Конструктор класса BinaryReader также в качестве параметра принимает объект потока, только в данном случае устанавливаем в качестве режима FileMode.Open: new BinaryReader(File.Open(«person.dat», FileMode.Open)) .

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

      Или подобным образом считаем данные из файла people.dat, который был записан в примере выше и который содержит данные объектов Person:

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

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *