Блоковый ввод/вывод (двоичные файлы)

Для чтения и записи двоичных файлов в файловой системе языка С имеется две функции: fread() и fwrite(). Эти функции позволяют читать и записывать блоки данных любого типа. Их прототипы следующие:

size_t fread (void *буфер, size_t колич_байт, size_t счетчик, FILE *уф);

size_t fwrite (const void *буфер, size_t колич_байт, size_t счетчик, FILE *уф);

Для fread() буфер – это указатель на область памяти, в которую будут прочитаны данные из файла. А для fwrite() буфер – это указатель на данные, которые будут записаны в файл. Значение счетчик определяет, сколько считывается или записывается элементов данных, причем длина каждого элемента в байтах равна колич_байт. (Тип size_t определяется как одна из разновидностей целого типа без знака.) И, наконец, уф – это указатель файла, то есть на уже открытый поток.

Функция fread() возвращает количество прочитанных элементов. Если достигнут конец файла или произошла ошибка, то возвращаемое значение может быть меньше, чем счетчик. А функция fwrite() возвращает количество записанных элементов. Если ошибка не произошла, то возвращаемый результат будет равен значению счетчик.

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

В качестве иллюстрации работы с двоичным файлом приведём фрагменты программ для записи в файл и чтения из файла одномерного массива. Для краткости функции открытия fopen() и закрытия fclose() файла опущены.

Запись в файл:

1) поэлементная запись

const int Nmax = 10; // максимальная размерность массива

int Mas[Nmax];

int N; // реальная размерность массива

for (int i = 0; i < N; i++)

fwrite(Mas, sizeof(Mas[i]), N, fp);

Вместо Mas можно использовать &Mas[0], а вместо sizeof(Mas[i]) – sizeof(int).

2) блоковая запись – 1-й вариант. Здесь в качестве размера блока указан размер одного элемента массива sizeof(int), а в качестве количества блоков – количество элементов массива N.

fwrite(Mas, sizeof(int), N, fp);

3) блоковая запись – 2-й вариант. Здесь в качестве размера блока указан размер всего массива sizeof(int) * N, а количество блоков, соответственно, равно единице.

fwrite(Mas, sizeof(int) * N, 1, fp);

4) блоковая запись – 3-й вариант. Используется тогда, когда реальная размерность массива совпадает с максимальной.

fwrite(Mas, sizeof(Mas), 1, fp);

Пример чтения из файла представлен для случая, когда известен тип массива Mas (например, int), но не известно количество элементов. В примере использовано то обстоятельство, что функция fread() является типизированной и возвращает количество прочитанных блоков.

int Mas[Nmax];

int i, temp, N;

i = 0;

while (fread(&temp, sizeof(int), 1, fp)!= 0)

{

Mas[i] = temp;

i++;

}

N = i;

Поскольку размерность массива, записанного в файл, не известна, чтение продолжается до тех пор, пока не будет достигнут конец файла. До начала цикла номер элемента массива i принимает начальное значение. Затем очередной элемент массива считывается из файла в промежуточную переменную temp. Если чтение было успешным, то функция fread() возвращает 1 (т.е. количество прочитанных элементов). Тогда прочитанное значение копируется из переменной temp в соответствующий элемент массива Mas[i], после чего номер элемента i увеличивается на единицу. Если же был достигнут конец файла и очередной элемент прочесть не удалось, то функция fread() возвращает 0, и цикл чтения массива из файла завершается. При этом количество реально прочитанных элементов N будет равно текущему значению переменной i.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: