Перейти к содержимому

Как читать бинарные файлы

  • автор:

Как читать бинарные файлы

Работа с бинарными файлами производится посредством посимвольного чтения-записи. Поскольку один объект char соответствует одному байту, то фактически речь идет о побайтовых записи/чтения.

Запись файла

Для записи символа в файл применяется функция putc() , которая имеет следующий прототип:

int putc(int c, FILE *stream);

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

#include int main(void) < // записываемая строка char message[] = "Hello METANIT.COM!"; // файл для записи char * filename = "data.txt"; // находим длину записываемой строки int n = sizeof(message)/sizeof(message[0]); FILE * fp= fopen(filename, "w"); if(fp) < // посимвольно записываем в файл for(int i=0; i < n; i++) < putc(message[i], fp); >fclose(fp); printf("File has been written\n"); > >

Здесь мы пробегаемся по массиву символов message и каждый из них заносим в файл data.txt (который располагается в текущей папке), передавая каждый символ в функцию putc() .

Чтение файла

Для чтения одного символа применяется функция getc() (функция fgetc() аналогична). Она имеет следующий прототип:

int getc(FILE *stream);

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

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

Считаем ранее записанный файл data.txt :

#include int main(void) < // символ для считывания char c; // файл для чтения char * filename = "data.txt"; FILE * fp= fopen(filename, "r"); if(fp) < // считываем посимвольно из файла while((c=getc(fp))!= EOF) < printf("%c", c); >fclose(fp); > >

Здесь считываем по одному символу из файла через вызов getc() . Здесь стоит обратить внимание на процесс считывания файла. Когда будет достигнут конец файла, функция getc() возвратит значение EOF («end of file» — конец файла)., которое определено в файле stdio.h. Поэтому мы можем считывать файл, пока не получим значение EOF.

В итоге на консоль будет выведено ранее записанное сообщение.

Чтение бинарных файлов с помощью Python

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

Когда бинарный файл требуется просмотреть или переместить, содержимое файла переводится в формат, понятный человеку. Бинарный файл имеет расширение .bin. Прочитать его можно с помощью встроенной функции или модуля. В этом уроке мы разберём различные способы чтения бинарных файлов с помощью Python.

Подготовка

Перед тем, как начать урок, желательно создать один или несколько бинарных файлов, чтобы воспользоваться скриптом из примера. Ниже представлены два скрипта на Python, которые создадут два бинарника. Файл binary1.py создаёт string.bin, содержащий строковые данные, а binary2.py – number_list.bin со списком из числовых данных.

Binary1.py

# Создаём бинарный файл file_handler = open("string.bin", "wb") # Добавляем две строки в бинарный файл file_handler.write(b"Welcome to LinuxHint.\nLearn Python Programming.") # Закрываем чтение file_handler.close()

Binary2.py

# Создаём бинарный файл file=open("number_list.bin","wb") # Объявляем список с числовыми данными numbers=[10,30,45,60,70,85,99] # Конвертируем список в массив barray=bytearray(numbers) # Записываем массив в файл file.write(barray) file.close()

Считываем бинарный файл со строковыми данными в массив байтов

В Python существует множество способов прочитать бинарный файл. Можно прочитать определённое количество байтов или весь файл сразу.

В приведенном ниже коде функция open() открывает для чтения string.bin, а функция read() на каждой итерации цикла while считывает по 7 символов в файле и выводит их. Далее мы используем функцию read() еще раз, но уже без аргументов — для считывания всего файла. После считывания содержимое выводится на экран.

# Открываем бинарный файл на чтение file_handler = open("string.bin", "rb") # Читаем первые 7 байтов из файла data_byte = file_handler.read(7) print("Print three characters in each iteration:") # Проходим по циклу, чтобы считать оставшуюся часть файла while data_byte: print(data_byte) data_byte = file_handler.read(7) # Записываем всё содержимое файла в байтовую строку with open('string.bin', 'rb') as fh: content = fh.read() print("Print the full content of the binary file:") print(content)

Результат

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

Считываем бинарный файл со строковыми данными в массив

Следующий скрипт поможет нам прочитать бинарник number_list.bin, созданный нами ранее.

# Открываем на чтение бинарный файл file = open("number_list.bin", "rb") # Считываем в список первые 5 элементов number = list(file.read(5)) # Выводим список print(number) # Закрываем файл file.close()

Бинарный файл содержит список с числовыми данными. Как и в предыдущем примере, функция open() открывает файл и читает из него данные. Затем из бинарника читаются первые 5 чисел и перед выводом объединяются в список.

Результат

После выполнения скрипта мы получим следующий результат. Бинарный файл содержит 7 чисел, первые 5 вывелись на консоль.

Читаем бинарный файл с помощью NumPy

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

Функция tofile() создаёт текстовый или бинарный файл, а fromfile() считывает данные из файла и создаёт массив.

Синтаксис tofile()

ndarray.tofile(file, sep='', format='%s')

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

Синтаксис fromfile()

numpy.fromfile(file, dtype=float, count=- 1, sep='', offset=0, *, like=None)

Первый аргумент обязательный – он принимает имя файла, путь или строку. Содержимое файла будет прочитано, только если вы укажете имя файла. dtype определяет тип данных в возвращаемом массиве. Count задаёт число элементов массива. Sep – для разделения элементов текста или массива. Offset определяет позицию в файле, с которой начинается считывание. Последний аргумент нужен, чтобы создать массив, не являющийся массивом NumPy.

Напишем следующий код, чтобы создать бинарный файл с помощью массива NumPy, прочитать его и вывести содержимое.

# Импортируем NumPy import numpy as np # Объявляем массив numpy nparray = np.array([34, 89, 30, 45, 90, 11]) # Создаём бинарный файл из numpy-массива nparray.tofile("list.bin") # Выведем данные из бинарного файла print(np.fromfile("list.bin", dtype=np.int64))

Результат

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

Заключение

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

Как читать бинарные файлы

• Функция READBIN(«file», «type», [[endian], [cols], [skip], [maxrows]]) возвращает массив, содержащий бинарные данные, записанные в файле file .

• Функция WRITEBIN(«file», «type», endian, M) записывает массив из скаляров в бинарный файл данных с именем file .

• file — строка, содержащая имя файла или полный путь с именем файла.

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

◦ byte — 8-разрядное целое число без знака.
◦ double — 64-разрядное число с плавающей точкой.
◦ float — 32-разрядное число с плавающей точкой.
◦ int16 — 16-разрядное целое число со знаком.
◦ int32 — 32-разрядное целое число со знаком.
◦ uint16 — 16-разрядное целое число без знака.
◦ uint32 — 32-разрядное целое число без знака.

• Аргумент endian (необязательный для функции READBIN ) задает порядок размещения данных в файле: обратный (вначале старший разряд) или прямой порядок данных (вначале младший разряд). Обратный порядок данных задается значением 1, прямой порядок — значением 0. Если значение не указано, принимается 0.

Если порядок данных неизвестен (обратный порядок принят в стандарте Macintosh, прямой порядок — в стандарте IBM-PC), обратитесь к документации источника данных, чтобы доверять результатам, полученным с помощью функций READBIN и WRITEBIN .

• cols (необязательный) — положительное целое число — количество столбцов на строку во входном файле. По умолчанию 1.

• skip (необязательный) — неотрицательное целое число — количество байтов в начале файла, которые нужно игнорировать при чтении данных. По умолчанию 0.

• maxrows (необязательный) — неотрицательное целое число — максимальное количество строк данных, которые требуется прочитать из файла. По умолчанию 0 (без ограничений).

Чтение бинарного файла на си

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

 // структура struct st < char* nam; int count; >; // сама запись в файл FILE* fp = fopen("file.bin", "wb+"); char new_str = '\n'; if (fp == NULL) < printf("Can't open file\n"); return; >for (int i = 0; i < size; i++) < fwrite(&(st[i].nam), sizeof(char), strlen(st[i].nam), fp); fwrite(&(st[i].count), sizeof(int), 1, fp); fwrite(&(new_str), sizeof(char), 1, fp); >fclose(fp); FILE* fp = fopen("file.bin", "rb"); if (fp == NULL) < printf("Can't open file\n"); return; >rewind(fp); for (int i = 0; i < size; i++) < fread(&(st[i].nam), sizeof(char), strlen(st[i].nam), fp); fread(&(st[i].count), sizeof(int), 1, fp); >fclose(fp); 

Отслеживать

задан 15 окт 2020 в 8:28

173 10 10 бронзовых знаков

Приведите пример структуры файла

15 окт 2020 в 8:30

В бинарных файлах нету «новой строки». Есть только бинарные данные (байты).

15 окт 2020 в 8:34

Строку я добавил самостоятельно, перенос

15 окт 2020 в 8:34

Что вы хотели сказать написав strlen(st[i].nam) ? массив символов nam уже чем-то инициализирован?

15 окт 2020 в 8:35

Приведите код — структуры и того, как вы записываете в файл. Без этого вряд ли получится. Особенно если вы читаете столько, сколько уже содержится 🙂 — strlen(st[i].nam) при чтении как-то странновато. «Странно, если не сказать большего» (с)

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

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