Save & Load Sets?

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



LVL 11
shaneholmesAsked:
Who is Participating?
 
Russell LibbyConnect With a Mentor Software Engineer, Advisory Commented:

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
 
shaneholmesAuthor Commented:
Sorry, typo mistake


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

Shane
0
 
shaneholmesAuthor Commented:
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
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

 
shaneholmesAuthor Commented:
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
 
shaneholmesAuthor Commented:
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
 
Russell LibbySoftware Engineer, Advisory Commented:
Anytime ;-)

And thank you,
Russell

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.