Solved

Save & Load Sets?

Posted on 2004-03-29
6
204 Views
Last Modified: 2010-04-05
I am trying to save & load a large amount of set data, to and from file using streams.

I have made an example of what I am trying to do.

It seams the writing to file works fine, but it crashes on the loading from file portion

Here is basically what I have:

Type

 TAnimal = (Dog, Cat, Horse, Cow, Squirrel);
 TAnimals = set of TAnimal;


var
 Animals: TAnimals;
 Animal: TAnimal;


//returns the number of items in Set
function GetAnimalCount(AAnimals: TAnimals): Integer;
var
 AAnimal: TAnimal;
begin
  result:= 0;
  for AAnimal:=  Low(AAnimal) to High(AANimal) do
   if AAnimal in AAnimals then  Result:= Result + 1;
end;



Here is where I save to file

 MemStr:= TMemoryStream.Create;

 WriteStreamInt(MemStr, GetAnimalCount(Animals));
 
 for Animal := Low(Animal) to High(Animal) do
  if Animal in Animals then
   WriteStreamStr(MemStr, GetEnumName(TypeInfo(TAnimal), Ord(Animal)));

  MemStr.SaveToFile(fFileName);
  MemStr.Free


here is where I load from file


 MemStr:= TMemoryStream.Create;
 MemStr.LoadFromFile(fFileName);
   
Count:= ReadStreamInt(MemStr);
for I:= 0 to Count - 1 do
 begin
  AnimalStr:= ReadStreamStr(MemStr);
  Include(Animals, TAnimal(GetEnumValue(TypeInfo(TAnimal),AnimalStr)));
 end;
MemStr.Free;

Using a showmessage in teh load from file, i can show the first item read in, but then it crashes.

Shane



0
Comment
Question by:shaneholmes
  • 4
  • 2
6 Comments
 
LVL 11

Author Comment

by:shaneholmes
ID: 10709975
Sorry, typo mistake


for Animal := Low(TAnimal) to High(TAnimal) do

Shane
0
 
LVL 11

Author Comment

by:shaneholmes
ID: 10710039
This is definitly where it crashes  

Include(Animals, TAnimal(GetEnumValue(TypeInfo(TAnimal),AnimalStr)));
 
I have also tried:

Animals:= Animals + TAnimal(GetEnumValue(TypeInfo(TAnimal),AnimalStr));

and

Animals:= Animals + [TAnimal(GetEnumValue(TypeInfo(TAnimal),AnimalStr))];

Shane
0
 
LVL 26

Accepted Solution

by:
Russell Libby earned 250 total points
ID: 10710157

Not sure if this helps, but the following compiles and executes correctly on D5.

// Read/Write functions taken from TReader and TWriter respectively

function GetAnimalCount(AAnimals: TAnimals): Integer;
var  AAnimal:    TAnimal;
begin
  result:=0;
  for AAnimal:=Low(AAnimal) to High(AAnimal) do
     if AAnimal in AAnimals then  Inc(result);
end;

procedure WriteStreamInt(Stream: TStream; Value: Integer);
begin
  Stream.Write(Value, SizeOf(Value));
end;

function ReadStreamInt(Stream: TStream): Integer;
begin
  Stream.Read(result, SizeOf(Integer));
end;

function ReadStreamStr(Stream: TStream): String;
var  dwLength:   Integer;
begin
  Stream.Read(dwLength, SizeOf(Integer));
  SetLength(result, dwLength);
  Stream.Read(Pointer(result)^, dwLength);
end;

procedure WriteStreamStr(Stream: TStream; Value: String);
var  dwLength:   Integer;
begin
  dwLength:=Length(Value);
  Stream.Write(dwLength, SizeOf(Integer));
  Stream.Write(Pointer(Value)^, dwLength);
end;

procedure SetSaveToFile(FileName: String);
var  MemStream:  TMemoryStream;
     AAnimal:    TAnimal;
begin
  MemStream:=TMemoryStream.Create;
  WriteStreamInt(MemStream, GetAnimalCount(Animals));
  for AAnimal:=Low(Animal) to High(Animal) do
     if AAnimal in Animals then
        WriteStreamStr(MemStream, GetEnumName(TypeInfo(TAnimal), Ord(AAnimal)));
  MemStream.SaveToFile(FileName);
  MemStream.Free
end;

procedure SetLoadFromFile(FileName: String);
var  MemStream:  TMemoryStream;
     dwIndex:    Integer;
     dwCount:    Integer;
begin
  MemStream:=TMemoryStream.Create;
  MemStream.LoadFromFile(FileName);
  Animals:=[];
  dwCount:=ReadStreamInt(MemStream);
  for dwIndex:=0 to Pred(dwCount) do
     Include(Animals, TAnimal(GetEnumValue(TypeInfo(TAnimal), ReadStreamStr(MemStream))));
  MemStream.Free
end;

----

begin

  Animals:=[Dog, Horse];
  SetSaveToFile('c:\test.txt');
  Animals:=[];
  SetLoadFromFile('c:\test.txt');
  if Animals = [Dog, Horse] then
     ShowMessage('Correct');

end;


Regards,
Russell

0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 11

Author Comment

by:shaneholmes
ID: 10710174
Russel, im in the middle of something right now, but i will get back to this in a bit and test it.

If it compiles and runs on your machine, im sure it will on mine.

Thanks!

Shane

0
 
LVL 11

Author Comment

by:shaneholmes
ID: 10710251
Hey Russell, after reviewing your code, I found two problems, fixed them and boom - works like a charm.

Sometimes youc an stare at code for ever and never see it. I knew smeone else would be able to right away!

Thanks for the boost!

Shane
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 10710268
Anytime ;-)

And thank you,
Russell

0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question