Forum > General

save open records to disk

(1/5) > >>

clemmi:
Is there a way to save a record to disk to be later on read from disk.

I know how to save the text from a memo, but I wonder if there's a way to do the same with a record or an array of records without going through the memo. Like be able to update the array of records from a previous save.

I found a Delphi reference using a stream but it seems to be for a console setup (strm.write/read, etc.) not a for GUI application like the one I'm working on. Maybe there's a way to adapt it. Any references available?

The idea is to save stages of a scheduling program at various times without having to reenter and process the data again.
Thanks.
_cl

taazz:
Show us the code, specifically I want to see the record definition and any code you have tested so far. As for your question the answer is yes it is possible to save a record on disk and later read it.

clemmi:
This is the reference I found:
http://stackoverflow.com/questions/3820996/delphi-2010-how-to-save-a-whole-record-to-a-file

I don't know how to use it on a GUI application. It uses strm.write and strm.read  which seems to be console code. I think it need to be use with Open/SaveDialogs in GUI application. Not sure how stream works.

You say: "As for your question the answer is yes it is possible to save a record on disk and later read it.".

Do you have a sample code? I should be able to take from that to my specific application.
thanks!
-cl

Blaazen:
IMO good example on that page is down ("myFile   : File of TCustomer;"). It is typical "file of records".


--- Quote ---I think it need to be use with Open/SaveDialogs in GUI application.
--- End quote ---
There is no difference in save/load files in console/GUI applications. After all, Open/SaveDialogs only selects a filename and path, they don't save/load anything themselves.

taazz:
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.

--- Code: ---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;

--- End code ---
2) a simple stream based load/save mechanism a more modern mechanism which should have better future than an untyped file.


--- Code: ---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;

--- End code ---

Navigation

[0] Message Index

[#] Next page

Go to full version