PDA

View Full Version : Saving a Dynamic Record Array to a file....



MrLobster
08-05-2004, 04:45 AM
How can i save this dynamic record array quickly in delphi?


type
tSinglePlayer = record
Name : string;
Numbers : array of integer;
end;

tPlayer : array of tSinglePlayer

tDatabase = record
Player : tPlayer;
end;

var
Database : tDatabase;


I previously used to use a simple piece of code to export the main database record.


var
DatabaseFile : file of tDatabase;

begin
AssignFile(DatabaseFile, 'database.txt');
Rewrite(DatabaseFile);
writeln(DatabaseFile, Database);
reset(DatabaseFile);
end;

However now that i have moved from static arrays to dynamic arrays, i get an error stating that 'tGame' needs finalization - not allowed in file type.

NOTE: there is a lot more record types for each player than above and there could be up too 100,000 players...

check out my game PAOL to see why, www.fresh-lobster.tk

cairnswm
08-05-2004, 06:42 PM
A file of <type> must have fixed length records. Because its a dynamic array the file doesn;t know how large the records are going to be and therefore cannot allocate space on the disk for it.

The best solution is to use two files.

MainFile = File of Player Detail Record

ChildFile = File of Recurring details record;

Then the recurring detail record has a link id back to the primary record

Harry Hunt
10-05-2004, 06:59 AM
The lazyman's solution to your problem:

Use TCollections instead of arrays (your arrays are one-dimensional anyway).
Then create a TComponent decendant with one of your collections as property and then you can just save that with TStream.SaveComponentRes

The slightly more painful way would be to add a "Length" variable to all your records that contain an array and then to write the arrays to disk manually basically like this:

Stream.Write(MyArray[I].SomeIntegerValue, SizeOf(Integer));
Stream.Write(MyArray[I].Length, SizeOf(Integer));
for J := 0 to Length(MyArray[I].SomeSubArray) - 1 do
Stream.Write(MyArray[I].SomeSubArray[J].SomeValue, SizeOf(Integer);

MrLobster
11-05-2004, 12:13 PM
Ok but setting the length is not what i am intending to do. I need it to be anysize i want. Never liked streams anyway :P

Would it be better to use a the database within delphi, if so any demonstration programs out there of one??

cairnswm
11-05-2004, 12:48 PM
Consider using Access and the ADO components to link to it.

I used to use a component called QDB (QuickDatabase) which was a record based database. Not sure if you'll find it anywhere though.

Ultra
12-05-2004, 12:16 AM
You need to have an untyped file if you want to save a record with dynamic content. The code would look something like this (untested):


procedure SaveRec(const P: TSinglePlayer);
var
len: Integer;
f: File;
begin
AssignFile(f, MY_FILE_NAME);
try
Rewrite(f, 1);
len := Length(P.Numbers);
BlockWrite(f, len, SizeOf(len));
BlockWrite(f, p.Numbers[0], SizeOf(P.Numbers[0]) * len);
len := Length(P.Name);
BlockWrite(f, len, SizeOf(len));
BlockWrite(f, P.Name[0], SizeOf(P.Name[0]) * len);
finally
CloseFile(f);
end;
end;


I'll let you play around with the code on your own now since I'm to tired to write anymore. :wink: