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

         

Ударим классом по двоичному файлу


Для начала выполним чисто косметические действия: оформим в виде отдельного класса файловый поток ввода вывода (fstream) в режиме работы с двоичным файлом произвольного доступа.


//------------------------------------------------------bk8-01.cpp


&#35include &#60fstream.h&#62
&#35define FNULL -1L
typedef int BOOL;
typedef long FPTR; // Тип - указатель в файле


typedef unsigned char _FAR *BUF; // Тип - указатель буфера


// файла в stdio


class TElem;
class BinFile : public fstream
{
public:
BOOL Create(char *); // Создать пустой файл


BOOL Open(char *); // Открыть существующий


FPTR Size() // Получить длину файла и


{ seekg(0L,ios::end); // позиционироваться на


return(tellg()); } // конец файла


void *VSZLoad(int&#38); // Функции для работы с




FPTR VSZAppend(void*,int); // записями переменной


FPTR VSZUpdate(void*,int,int); // длины


BinFile() { fstream(); } //


~BinFile(){ close();} //


};


BOOL BinFile::Create(char *s)
{
int a=1;
open(s, ios::trunc | ios::out | ios::binary );
if (good()) { close(); return(1); }
return(0);
}


BOOL BinFile::Open(char * s)
{
open(s,ios::in | ios::out | ios::binary);
return(good());
}


// До сих пор функции-элементы класса представляли


// собой практически чистые вызовы библиотечных функций.


// Но поскольку значительное число объектов имеет переменную


// размерность, то класс BinFile полезно дополнить функциями,


// работающими с записями переменной длины. Напомним, что


// запись переменной длины в файле представлена целой пере-


// менной - счетчиком и следующими за ними байтами данных,


// число которых определяется счетчиком. */


//------ При загрузке записи переменной длины память


// под нее выделяется в виде динамического массива


void *BinFile::VSZLoad(int &#38sz)
{
char *pdata;
read((BUF)&#38sz, sizeof(int));
if (!good()) return(NULL);
if ((pdata = new char[sz])==NULL ) return(NULL);
read((unsigned char *)pdata,sz);
if (good()) return((void *)pdata);
delete pdata;
return(NULL);
}


//----- При выводе записи переменной длины на место уже



// существующей проверяется размерность старой записи.

// Если она недостаточна, новая запись добавляется в конец

// файла. Значение параметра mode=1 устанавливает режим

// проверки.

FPTR BinFile::VSZUpdate(void *buf ,int sz, int mode)
{
int oldsz;
FPTR pos;
pos = tellg();
if (mode)
{
read((BUF)&#38oldsz,sizeof(int));
if (!good()) return(FNULL);
if (oldsz &#60 sz) return(VSZAppend(buf,sz));
seekg(pos);
if (!good()) return(FNULL);
}
write((BUF)&#38sz,sizeof(int));
write((BUF)buf,sz);
if (!good()) return(FNULL);
return(pos);
}

FPTR BinFile::VSZAppend(void *buf ,int sz)
{
FPTR pos;
if ((pos = Size()) ==FNULL) return(FNULL);
write((BUF)&#38sz,sizeof(int));
write((BUF)buf,sz);
if (!good()) return(FNULL);
return(pos);
}

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