
              ͻ
                                                       
                  FileRead Programmer's Library 1.0    
                                                       
              ͹
                                                       
                     Copyright 1992, Tom Clancy        
                        All Rights Reserved            
                                                       
              ͼ



INTRODUCTION

     The FileRead programmer's library is a set of tools that allow you,
the programmer, to open and manipulate a data file with any data type
you choose.  It's fully object oriented and extensible so using this
database is as easy as declaring an instance of the TFread object,
initializing the file, then manipulating the data.

SHAREWARE NOTICE

     FileRead is shareware, not freeware, and a donation of $20.00 is
asked for the registration and use of this product.  This is a
programmer's tool.  I require no special registration for commercial use
or for use in a software company, as long as the product is registered
under that company's name and this toolkit is used for developing
software, either for commercial use or in-house, specifically for that
company.

REQUIREMENTS

     This toolkit requires Turbo Pascal 6.0 and will work on anything
that Turbo Pascal 6.0 will work on, including my lowly tandy 1000 SX,
the computer on which I designed FileRead.

FILES

     You should have the following files in your distribution disk or
archive:

     Fileread.Pas........The fileread library source code
     Fileread.Tpu........The fileread library Tpu version 6 format
     Fileread.Txt........This documentation
     Test.Pas............Test #1 source code
     Test2.Pas...........Test #2 source code
     L.Exe...............File listing program
     Readme.Bat..........Batch file to launch file viewer
     Register.Doc........Registration form to be filled out and sent in

     If you do not have the complete set of files, then either notify
the sysop of the board from which you downloaded it, or, when you send
in the registration, you will receive a new disk with the latest
version.

     If you do not have all the files in your archive and would like to
have the full version for evaluation before registering, then call me or
send me a letter and we'll work out a way to get you the complete set of
files.

METHOD AND OBJECT SUMMARY

     The following is the FileRead object and a description of each
method plus example source code on how to use each method.

***********************************************************************

   TFreadPtr = ^TFreadObj;  {Pointer to the TFread object}
   TFreadObj = Object
     Constructor Init(fn : string; mode:integer; recsize : longint);
     Destructor  Done;

     { random access methods. }
     Procedure   ReadRec(var frec; fpos:longint);  virtual;
     Procedure   WriteRec(var frec; fpos:longint); virtual;

     { sequential access methods. }
     Procedure   AppendRec(var frec);
     Procedure   ReadNext(var frec);
     Procedure   ReadPrevious(var frec);
     Procedure   ReadCurrent(var frec);

     { various file modification methods. }
     Procedure   EraseFile;
     Function    RenameFile(fn:string):boolean;

     { miscellaneous functions and error flag functions. }
     Procedure   Rewind;
     Function    NumRecs     : Longint;
     Function    GetFilename : String;
     Function    GetCurrent  : Longint;
     Function    OpenError   : boolean;
     Function    ReadError   : boolean;
     Function    WriteError  : boolean;
   End;

***********************************************************************


Constructor Init(fn : string; mode:integer; recsize : longint);

     The constructor takes, as its parameters, the filename in a String
format, the mode for which TFread will initialize the file with, and the
size of the records that will be stored in and retrieved from the file.

     The file name can be a single filename such as INFO.DAT, or it can
handle a path, such as C:\DATABASE\DATA\INFO.DAT.

     The mode can be one of three choice, OPEN, CREATE, or OPENCREATE.

     OPEN

          will attempt to open the file.  If the file does not exist,
     then the OpenError flag will be set.

     CREATE

          will attempt to create the file whether or not it exists.
     If the file does exist, then it will be rewritten, unallocating the
     data that was previously in the file.  If it cannot create the file
     for some reason, then the OpenError flag will be set.

     OPENCREATE

          will first attempt to open the file specified.  If the
     file does not exist, TFread will then attempt to create the file.  If
     the file, for some reason, cannot be created, then the OpenError flag
     will be set.

Example:

     Type
       InfoRec : Record
         Name : String[25];
         Address : String[25];
         City : String[25];
         State : String[2];
         ZipCode : String[5];
       end;

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InforRec;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoRec)));
       . . .
     End;


----------------------------------------------------------------------------

Destructor  Done;

     The destructor will close the file, setting the OpenError flag to
true so that you cannot access any of the methods.

Example:

     Type
       InfoRec : Record
         Name : String[25];
         Address : String[25];
         City : String[25];
         State : String[2];
         ZipCode : String[5];
       end;

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InforRec;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoRec)));
       . . .
       Dispose(MyFile,Done);
     End;


----------------------------------------------------------------------------

Procedure   ReadRec(var frec; fpos:longint);

     ReadRec will read a record at the specified location, returning it
in the variable frec.  If an invalid File Position (fpos) is passed to
the procedure, or if for some reason ReadRec could not access the file
data at the specified location, then the ReadError flag will be set.

Example:

     Type
       InfoRec : Record
         Name : String[25];
         Address : String[25];
         City : String[25];
         State : String[2];
         ZipCode : String[5];
       end;

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InforRec;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoRec)));

       MyFile^.ReadRec(Info,0);  {Read the first record in the data file}

       Dispose(MyFile,Done);
     End;

----------------------------------------------------------------------------

Procedure   WriteRec(var frec; fpos:longint);

     WriteRec will write a record passed in as Frec at the file position
pointed to by fpos.  If the file position passed to WriteRec is invalid
or if for some reason WriteRec cannot write a record at the specified
location, then the WriteError flag will be set.

Example:

     Type
       InfoRec : Record
         Name : String[25];
         Address : String[25];
         City : String[25];
         State : String[2];
         ZipCode : String[5];
       end;

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InforRec;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoRec)));

       with info do
       begin
         Name:='Tom Clancy';
         Address:='5861 Horseshoe Drive';
         City:='Bethel Park';
         State:='PA';
         ZipCode:='15102';
       end;

       MyFile^.WriteRec(Info,10); {Update the 10th record in the file}
       MyFile^.ReadRec(Info,10);  {Read the 10th record from in data file}

       Dispose(MyFile,Done);
     End;

----------------------------------------------------------------------------

Procedure   AppendRec(var frec);

     AppendRec is a sequential access method for appending records to
the end of the data file.  Like WriteRec, if AppendRec cannot append a
record to the file, the WriteError flag will be set.

Example:

     Type
       InfoType : Word;  {A file of unsigned integers!}

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InfoType;
       i : integer;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoType)));

       Randomize;  {randomize the random seed}
       {append 100 integers to the data file.}
       for i:=1 to 100 do
       begin
         Info:=Random(65535);
         MyFile^.AppendRec(Info);
       end;

       Dispose(MyFile,Done);
     End;

----------------------------------------------------------------------------

Procedure   ReadNext(var frec);

     ReadNext will read the next record in the file and return that
record in the frec variable.  If ReadNext tries to read past the end of
the file or if ReadNext gets an error when trying to read the next
record in the file then the ReadError flag will be set.

Example:

     Type
       InfoType : Word;  {A file of unsigned integers!}

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InfoType;
       i : integer;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoType)));

       MyFile^.ReadRec(Info,0);  {Start at first record!}

       {Read and display the 100 words created in the previous
        example.  When ReadError is set to true, we will have reached
        the end of the file.}

       while not MyFile^.ReadError do
       begin
         writeln(Info);
         Myfile^.Readnext(Info);
       end;

       Dispose(MyFile,Done);
     End;


----------------------------------------------------------------------------

Procedure   ReadPrevious(var frec);

     ReadPrevious, like ReadNext, is a sequential file accessing method,
but instead of reading forward in the file, it will read backwards
through the file, returning the previous record in the frec variable.
The ReadError flag will be set if ReadPrevious attempts to read a
record that's one less than the first record or if for some reason an
error occurs when trying to access the data file.

Example:

     Type
       InfoType : Word;  {A file of unsigned integers!}

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InfoType;
       i : integer;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoType)));

       MyFile^.ReadRec(Info,MyFile^.NumRecs);  {Start at last record!}

       {Read and display backwards the 100 words randomly created. }

       while not MyFile^.ReadError do
       begin
         writeln(Info);
         Myfile^.ReadPrevious(Info);
       end;

       Dispose(MyFile,Done);
     End;


----------------------------------------------------------------------------

Procedure   ReadCurrent(var frec);

     TFread keeps track of the current record (the last record that had
been read).  Using ReadCurrent will read the record at the Current
location and return it in Frec.  The same conditions apply for ther
ReadError flag as they do in the previous file read methods.

Example:

     Type
       InfoType : Word;  {A file of unsigned integers!}

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InfoType;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoType)));

       . . .

       MyFile^.ReadCurrent(Info);  {Reads the current record into Info}

       Dispose(MyFile,Done);
     End;

----------------------------------------------------------------------------

Procedure   EraseFile;

     Erasefile will close the file then erase it from the disk.  Like
the Done destructor, once this procedure is called, then none of the
file accessing methods can be used because there will be no more file to
use them with.

Example:

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoType)));

       . . .

       MyFile^.EraseFile;  {Erases the current file}

       Dispose(MyFile,Done);
     End;

----------------------------------------------------------------------------

Function    RenameFile(fn:string):boolean;

     RenameFile will rename the file to the specified string passed in
as fn.  If the file could not be renamed (i.e. you are attempting to
rename a file to another file that already exists) then the function
will return false.  Renaming the file will in no way alter anything
within the object.  This function will just rename the physical file on
disk, leaving you where you last left off.

Example:

     Type
       InfoType : Word;  {A file of unsigned integers!}

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InfoType;
       Success : Boolean;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoType)));

       . . .

       MyFile^.ReadCurrent(Info);  {Reads the current record into Info}
       Success:=MyFile^.RenameFile('SOMETHING.DAT');

       {could we rename the file?}

       if Success then 
         MyFile^.ReadCurrent(Info);  {Still at same position}

       Dispose(MyFile,Done);
     End;

----------------------------------------------------------------------------

Procedure   Rewind;

     Rewind will reset the file pointer and the Current position to the
beginning of the file.

Example:

     Type
       InfoType : Word;  {A file of unsigned integers!}

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InfoType;
       i : integer;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoType)));

       for i:=1 to 10 do
       begin
         MyFile^.ReadRec(Info,i-1);
         Writeln(Info);
       end;
       {Now at the tenth record.}

       MyFile^.Rewind;   {Now at the first record!}

       . . .

       Dispose(MyFile,Done);
     End;

----------------------------------------------------------------------------

Function    NumRecs     : Longint;

     Numrecs will return the number of physical elements within the
file.  For instance, if you create a file of type integer and write 100
integers to disk, NumRecs will return 100.  The same applies for
records, or arrays, or whatever you wish to create a file of.

Example:

     Type
       InfoType : Word;  {A file of unsigned integers!}

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InfoType;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoType)));
       Writeln('Number of records in file: ',MyFile^.NumRecs);
       . . .

       Dispose(MyFile,Done);
     End;

----------------------------------------------------------------------------

Function    GetFilename : String;

     GetFilename will return the actual name of the file as it appears
on the disk.

Example:

     Type
       InfoType : Word;  {A file of unsigned integers!}

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InfoType;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoType)));
       Writeln('The name of the file is ',MyFile^.GetFilename);
       . . .

       Dispose(MyFile,Done);
     End;

----------------------------------------------------------------------------

Function    GetCurrent  : Longint;

     GetCurrent will return the physical record number where the object
TFread is currently pointing.

Example:

     Type
       InfoType : Word;  {A file of unsigned integers!}

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InfoType;
       i : integer;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoType)));

       {reads in the first 10 random numbers in the file and displays
        the physical record number and the generated random number}
       for i:=1 to 10 do
       begin
         MyFile^.ReadRec(Info,i-1);
         Writeln(MyFile^.GetCurrent:4,'  ',Info);
       end;

       Dispose(MyFile,Done);
     End;

----------------------------------------------------------------------------

Function    OpenError   : boolean;

     OpenError will return the status of the OpenError flag.  This flag
is set true if the file has been successfully opened or created.
Otherwise OpenError will be set to false.

Example:

     Type
       InfoType : Word;  {A file of unsigned integers!}

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InfoType;
       i : integer;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoType)));
       if MyFile^.OpenError then
         writeln('Error openning file, aborting!')
       else
         . . .
     End;

----------------------------------------------------------------------------

Function    ReadError   : boolean;

     ReadError will be set true if any of the read methods have
successfully read a record.  Otherwise this function will return a
false.

Example:

     Type
       InfoType : Word;  {A file of unsigned integers!}

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InfoType;
       i : integer;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoType)));
       if MyFile^.OpenError then
         writeln('Error openning file, aborting!')
       else
       begin
         MyFile^.ReadRec(Info,101);  {attempt to read record 101!}
         if MyFile^.ReadError then
           writeln('Could not read that record!');
         . . .
       end;
     End;

----------------------------------------------------------------------------

Function    WriteError  : boolean;

     WriteError will be set to true if any of the file write methods
have successfully writen the data to disk.  Otherwise this function will
return false.

Example:

     Type
       InfoType : Word;  {A file of unsigned integers!}

     Procedure DoSomething;
     Var
       MyFile : TFreadPtr;  {a pointer to the TFread object}
       Info : InfoType;
       i : integer;
     Begin
       New(MyFile,Init('TEST.DAT',OpenCreate,SizeOf(InfoType)));
       if MyFile^.OpenError then
         writeln('Error openning file, aborting!')
       else
       begin
         MyFile^.WriteRec(Info,200);  {attempt to update record 200!}
         if MyFile^.WriteError then
           writeln('Could not update that record!');
         . . .
       end;
     End;

----------------------------------------------------------------------------

Function Exist(fn:string) : Boolean;

     There is also a useful function in the interface section called
Exist which will return True if the file specified in the Fn string
variable exists.  This is used by the object but can also be used as a
stand alone procedure.

Example:

     If not Exist('TEST.DAT') then
       writeln('Error: Could not locate file!')
     else
       . . .

----------------------------------------------------------------------------

ENDING NOTES

     This is merely the first version of this software library, and no
attempts to include internal buffering have been attempted.  I am
planning with future releases to have some kind of internal buffering
that might make the file accessing faster.  Since this is an object,
however, you could take it upon yourself to write your own object which
would inherit mine and add your own buffering handler.

     Shareware, as you already may know, is an important part of today's
computing world.  I implore you, if you use shareware and don't register,
please do so.  Many authors out there would greatly appreciate the
donation and the incentive may be enough to encourage the author to
produce an even more robust version of his or her software.

     My address and telephone number follows as does the numbers of a
few bulletin boards where I can be reached:

     Thomas J. Clancy Jr.
     5861 Horseshoe Drive
     Bethel Park, PA 15102
     Home Phone: (412) 833-7754

     BBS's:

     The Titusville Connection : (814) 827-1234
     Century Products BBS      : (412) 831-5438
     Technicomm BBS            : (412) 885-4347
     Thiel College BBS         : (412) 589-2039
     SV Educational BBS        : (412) 962-0765



