ok here are 2 different approaches.
1) a pascal typed file the most common pre 1990 pascal database format and one of the reasons pascal was popular back then.
type
PMyRecord = ^TMyRecord;
TMyRecord = record
ID : cardinal;
FName : string[20];
LName : string[80];
BDay : TDateTime;
end;
TMyRecordFile = file of TMyRecord;
TMyRecordArray = array of TMyRecord;
procedure AppendMyRecord(const aRec:PMyRecord; aFilename:string);
function OpenMyRecFile(const aFilename:String):TMyRecordFile;
procedure CloseMyRecordFile(var aFile:TMyRecordFile);
procedure NextRecord(var aRec:TMyRecord; var aFile:TMyRecordFile);
function LoadAllRecords(const aFileName:String):TMyRecordArray;
procedure SaveRecords(Const aFilename:String; var aRecords : TMyRecordArray);
implementation
procedure SaveRecords(Const aFilename:String; var aRecords : TMyRecordArray);
var
vFile : TMyRecordFile;
vCntr : Integer;
begin
AssignFile(vFile, aFileName);
Rewrite(vFile);
for vCntr := Low(aRecords) to High(aRecords) do begin;
Write(vFile, aRecords[vCntr]);
end;
end;
function LoadAllRecords(const aFileName:String):TMyRecordArray;
var
vFile : TMyRecordFile;
vBuf : TMyRecord;
begin
AssignFile(vFile, aFileName);
Reset(vFile);
while not EOF(vFile) do begin
Read(vFile, vBuf);
SetLength(Result, Length(Result)+1);
Result[High(Result)] := vBuf;
end;
end;
procedure CloseMyRecordFile(var aFile:TMyRecordFile);
begin
CloseFile(aFile);
end;
function OpenMyRecFile(const aFilename:String):TMyRecordFile;
begin
AssignFile(Result,aFilename);
Reset(Reset);
end;
procedure AppendMyRecord(const aRec:PMyRecord; aFilename:string);
var
vFile : File of TMyRecord;
vTemp : TMyRecord;
begin
AssignFile(vFile,aFilename);
Reset(vFile);
try
while not EOF(vFile) do Read(vFile, vTemp);
Write(vFile,aRec^);
finally
CloseFile(vFile);
end;
end;
procedure NextRecord(var aRec:TMyRecord; var aFile:TMyRecordFile);
begin
if not eof(aFile) then Read(aFile,aRec);
end;
2) a simple stream based load/save mechanism a more modern mechanism which should have better future than an untyped file.
type
PMyRecord = ^TMyRecord;
TMyRecord = record
ID : cardinal;
FName : string[20];
LName : string[80];
BDay : TDateTime;
end;
TMyRecordArray = array of TMyRecord;
function LoadAll(const aFilename:String):TMyRecordArray;
function LoadAll_(const aFilename:String):TMyRecordArray;
procedure SaveAll(const aFileName:String; var aRecords:TMyRecordArray);
implementation
uses math;
{load them all in single read operation}
function LoadAll(const aFilename:String):TMyRecordArray;
var
vFile:TFileStream;
begin
vFile := TFileStream.Create(aFilename, fmOpenReadWrite or fmShareExclusive);
try
vFile.Seek(0,0);
SetLength(Result, ceil(vFile.Size / SizeOf(TMyRecord)) );
vFile.Read(Result[Low(result], vFile.Size);
finally
vFile.Free;
end;
end;
{load them all one by one.}
function LoadAll_(const aFilename:String):TMyRecordArray;
var
vFile:TFileStream;
begin
vFile := TFileStream.Create(aFilename, fmOpenReadWrite or fmShareExclusive);
try
vFile.Seek(0,0);
while vFile.Position < vfile.Size do begin;
SetLength(Result, Length(Result)+1);
vFile.Read(Result[high(Result]), SizeOf(TMyRecord));
end;
finally
vFile.Free;
end;
end;
//save all in a single write operation
procedure SaveAll(const aFileName:String; var aRecords:TMyRecordArray);
var
vFile : TFileStream = nil;
vTotal : cardinal = 0;
begin
vFile := TFileStream.Create(aFilename, fmOpenReadWrite or fmShareExclusive);
try
vTotal := SizeOf(TMyRecord) * (High(aRecords)-Low(aRecords));
vFile.Size := vTotal; //avoid appending byte by byte just allocate the hall thing if possible.
vFile.Seek(0,0);
vFile.Write(Result[Low(result], vTotal);
finally
vFile.Free;
end;
end;