Двоичные файлы
Двоичные файлы отличаются от текстовых тем, что представляют собой последовательность байтов, содержимое которых может иметь различную природу. Это могут быть байты, представляющие числовую информацию в машинном формате, байты с графическими изображениями, байты с аудиоинформацией и т.п. Содержимое таких байтов может случайно совпасть с управляющими кодами таблицы ASCII, но на них нельзя реагировать так, как это делается при обработке текстовой информации. Естественно, что единицей обмена с такими данными могут быть только порции байтов указанной длины.
Создание двоичных файлов с помощью функции fopen отличается от создания текстовых файлов только указанием режима обмена – "rb" (двоичный для чтения), "rb+" (двоичный для чтения и записи), "wb" (двоичный для записи), "wb+" (двоичный для записи и чтения):
FILE *f1;
.........
f1=fopen(имя_файла, "режим");
Обычно для обмена с двоичными файлами используются функции fread и fwrite:
c_w = fwrite(buf, size_rec, n_rec, f1);
Здесь
buf – указатель типа void* на начало буфера в оперативной памяти, из которого информация переписывается в файл;
size_rec – размер передаваемой порции в байтах;
n_rec – количество порций, которое должно быть записано в файл;
f1 – указатель на блок управления файлом;
c_w – количество порций, которое фактически записалось в файл.
Считывание данных из двоичного файла осуществляется с помощью функции fread с таким же набором параметров:
c_r = fread(buf, size_rec, n_rec, f1);
Здесь
c_r – количество порций, которое фактически прочиталось из файла;
buf – указатель типа void* на начало буфера в оперативной памяти, в который информация считывается из файла.
Двоичные файлы допускают не только последовательный обмен данными. Так как размеры порций данных и их количество, участвующее в очередном обмене, диктуются программистом, а не смыслом информации, хранящейся в файле, то имеется возможность пропустить часть данных или вернуться повторно к ранее обработанной информации. Контроль за текущей позицией доступных данных в файле осуществляет система с помощью указателя, находящегося в блоке управления файлом. С помощью функции fseek программист имеет возможность переместить этот указатель:
fseek(f1,delta,pos);
Здесь
f1 – указатель на блок управления файлом;
delta – величина смещения в байтах, на которую следует переместить указатель файла;
pos – позиция, от которой производится смещение указателя (0 или SEEK_SET – от начала файла, 1 или SEEK_CUR – от текущей позиции, 2 или SEEK_END – от конца файла)
Пример. Запись в бинарный файл строки «Hello».
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
using namespace std;
int main( )
{
FILE *Ptr;
char s[]="Hello";
Ptr=fopen("c.bin","wb");
fwrite(s,sizeof(s),1,Ptr);
fclose(Ptr);
}
Структурированные файлы
Структурированный файл является частным случаем двоичного файла, в котором в качестве порции обмена выступает структура языка C, являющаяся точным аналогом записи в Паскале. По сравнению с предыдущим примером использование записей позволяет сократить количество обращений к функциям fread/fwrite, т.к. в одном обращении участвуют все поля записи.
Инициализация структурированного файла выполняется точно таким же способом, как и подготовка к работе двоичного файла.
Пример.Запись в файл данных структуры (10 чисел, и их квадратов) и затем чтение записанных данных.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
using namespace std;
int main( )
{
FILE *Ptr;
struct {
char s[5];
int n;
float r;
} b;
strcpy(b.s,"Line");
Ptr=fopen("d.rec","wb");
for(int j=1;j<11;j++)
{ b.n=j; b.r=j*j;
fwrite(&b,sizeof(b),1,Ptr);
printf("\n%s %d %f",b.s,b.n,b.r);
}
fclose(Ptr);
Ptr=fopen("d.rec","rb");
for(int j=10; j>0; j--)
{ fseek(Ptr,(j-1)*sizeof(b),SEEK_SET);
fread(&b,sizeof(b),1,Ptr);
printf("\n%s %d %f",b.s,b.n,b.r);
}
getch();
fclose(Ptr);
}