Информатика и технология программирования

       

Файл записей переменной длины


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



-в первом случае, используется специальное значение или код -ограничитель записи. Типичным примером является строка текста в памяти, имеющая в качестве ограничителя символ '\0' , который в файле превращается в последовательность символов ' \r' и '\n'. В этом смысле обычный текстовый файл при работе с ним построчно есть файл записей переменной длины;



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

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


//------------------------------------------------------bk59-01.cpp


&#35include &#60stdio.h&#62
&#35include &#60alloc.h&#62
struct vrec
{
int dd,mm,yy;
char name[20]; // Строка фиксированной длины


char *addr; // Строка переменной длины


};


&#35define VSZ sizeof(vrec)


v rec *get(FILE *fd) // Чтение из файла в динамические


{ // переменные


int size;
vrec *p;
fread(&#38size,sizeof(int),1,fd); // Чтение счетчика




if (size == 0) return NULL; // EOF


if (size &#60 VSZ) return NULL; // Короткая запись


if ((p = new vrec) ==NULL) return NULL;
fread((void*)p,VSZ,1,fd); // Постоянная часть записи


size -= VSZ; // Остаток записи - строка


if ((p-&#62addr = new char[size]) ==NULL)
return NULL;
fread((void*)p-&#62addr,size,1,fd); // Переменная часть записи


return p;
}


void put(FILE *fd, vrec *p) // Добавление в файл


{
int size;
fseek(fd,-(long)sizeof(int),SEEK_END); // Установить на запись EOF


size = VSZ + strlen(p-&#62addr) + 1; // Общая длина записи (счетчик)


fwrite((void*)&#38size, sizeof(int), 1, fd); // Запись счетчика


f write((void*)p, VSZ, 1, fd); // Запись постоянной части


size -=VSZ;
fwrite((void*)p-&#62addr,size,1,fd); // Запись переменной части


size = 0; // Логический EOF-запись нулевой длины


fwrite((void*)&#38size, sizeof(int), 1, fd);
}



Содержание раздела