save two TStringList to FileStream

I have 2 TStringList

m_Text: TStringList;
m_Info: TStringList;

I have this text in m_Text :
"Text1"
"Text2"

and I have this text in m_Info :
"Info1"
"Info2"

I save it like this :

var
  Stream: TFileStream;

Stream := TFileStream.Create('Filename', fmCreate);
m_Text.SaveToStream(Stream);
m_Info.SaveToStream(Stream);
Stream.Free;

then I load it :

var
  Stream: TFileStream;

Stream := TFileStream.Create('Filename', fmCreate);
m_Text.LoadFromStream(Stream);
m_Info.LoadFromStream(Stream);
Stream.Free;

But instead of having text each like above I have the m_Text hold all of the text while m_Info is empty.

How to fix it ?
comicboyAsked:
Who is Participating?
 
MBoConnect With a Mentor Commented:
hi, comicboy
2 ways

1) saving
FS:TFileStream;
MS:TMemoryStream;

ms:= TMemoryStream.Create;
fs:= TFileStream.Create('e:\file.dat',fmCreate);

m_Text.SaveToStream(ms);
ms.Position := 0;
size := ms.Size;
fs.WriteBuffer( size, Sizeof(size));
fs.CopyFrom(ms, size );
ms.Clear;

m_Info.SaveToStream(ms);
ms.position := 0;
size := ms.Size;
fs.WriteBuffer( size, Sizeof(size));
fs.CopyFrom(ms, size );

ms.Free;
fs.Free;

loading

ms:= TMemoryStream.Create;
fs:= TFileStream.Create('e:\file.dat',fmOpenRead);

fs.ReadBuffer( size, sizeof(integer));
ms.CopyFrom(fs, size );
ms.Position := 0;
m_Text.LoadFromStream(ms);

ms.Clear;
fs.ReadBuffer( size, sizeof(integer));
ms.CopyFrom(fs, size );
ms.Position := 0;
m_Info.LoadFromStream(ms);

ms.Free;
fs.Free;

2) saving
fs:TFileStream;
size:integer;
s:string;

fs:= TFileStream.Create('e:\file.dat',fmCreate);

size:=length(m_text.CommaText);
fs.Write(size,sizeof(integer));
s:=m_text.CommaText;
fs.Write(s[1],size);

size:=length(m_info.CommaText);
fs.Write(size,sizeof(integer));
s:=m_info.CommaText;
fs.Write(s[1],size);

fs.free;

loading

fs:= TFileStream.Create('e:\file.dat',fmOpenRead);

fs.Read(size,sizeof(integer));
setlength(s,size);
fs.Read(s[1],size);
m_text.CommaText:=s;

fs.Read(size,sizeof(integer));
setlength(s,size);
fs.Read(s[1],size);
m_Info.CommaText:=s;

fs.free;

Both methods work fine.
Of course, don't forget to create StringLists
0
 
comicboyAuthor Commented:
Sorry for loading parameter is fmOpenRead instead of fmCreate sorry (I just copy it :p )
0
 
classicsCommented:
Save them to seperate files.
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

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.

 
nestoruaCommented:
HI, comicboy,
If you have both of the StringLists with the same "Count"
property (as in your example), you have to do the following:
//
procedure ReadFromFile(const FileName: string);
var SL: TStringList;
begin
SL:=TStringList.Create;
with SL do
try
LoadFromFile(FileName);  
m_Text.Clear;
for i:=0 to (Count div 2)-1 do
m_Text.Add(SL[i]);
m_Info.Clear;
for i:=(Count div 2) to Count-1 do
m_Info.Add(SL[i]);
finally
Free;  
end;
end;
//
procedure WriteToFile(const FileName: string);
var SL: TStringList;
begin
SL:=TStringList.Create;
with SL do
try
AddStrings(m_Text);
AddStrings(m_Info);
SaveToFile(FileName);  
finally
Free;  
end;
end;
Sincerely,
Nestorua.
0
 
comicboyAuthor Commented:
Hi classic, I think I know if I should separate it into 2 files :p hehehe but I need it within one file which infact I combine the file with another data too like bitmap and other data.

for Nestorua, the problem is both may have different count. But I think I can also add an integer header for each which let me know how many entry within each TStringList. I may try to program it...
0
 
classicsCommented:
Try using TInifile then, save each list under a different header (key).
0
 
nestoruaCommented:
HI, comicboy,
If you have them with different counts, then you can save them in TStream writing first there counts.
But the more elegant way is to use TReader and TWriter with
ReadListBegin, ReadListEnd, WriteListBegin and WriteListEnd methods.
Sincerely,
Nestorua.
0
 
JaccoCommented:
Another nice way:

procedure SaveStringLists(aStream: TStream; const aLists: array of TStrings);
var
  lW: TWriter;
  liList: Integer;
begin
  lW := TWriter.Create(aStream, 256);
  try
    lW.WriteListBegin;
    for liList := Low(aLists) to High(aLists) do
    begin
      lW.WriteString(aLists[liList].Text);
    end;
    lW.WriteListEnd;
  finally
    lW.Free;
  end;
end;

procedure LoadStringLists(aStream: TStream; const aLists: array of TStrings);
var
  lR: TReader;
  liList: Integer;
begin
  lR := TReader.Create(aStream, 256);
  try
    liList := Low(aLists);
    lR.ReadListBegin;
    while not lR.EndOfList do
    begin
      if liList <= High(aLists) then
        aLists[liList].Text := lR.ReadString;
      Inc(liList);
    end;
    lR.ReadListEnd;
  finally
    lR.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  lFS: TFileStream;
begin
  lFS := TFileStream.Create('d:\test.sls', fmCreate);
  try
    SaveStringLists(lFS, [Memo1.Lines, Memo2.Lines]);
  finally
    lFS.Free;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  lFS: TFileStream;
begin
  lFS := TFileStream.Create('d:\test.sls', fmOpenRead);
  try
    LoadStringLists(lFS, [Memo1.Lines, Memo2.Lines]);
  finally
    lFS.Free;
  end;
end;

This alse works with stringlists.

Regards Jacco
0
 
Lee_NoverCommented:
nice way with TReader and TWriter :)
0
 
comicboyAuthor Commented:
I think I I've better use the way MBo did (the 2nd one) since it's most closely what actually I need, even though it's not as sophiticated as using TReader and TWriter, but it's conventional and simplistic I do undestand, so sorry I'm newbies in Delphi.

While I also need to place several other data like TBitmap within single TFileStream (so the file may contain : arbitrary length text, record of data and several bitmaps) and so I can't use TINI file.

Thanks to all experts who trying to help you are all great and the best "MAHA GURU" in this world I know :)
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.