Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2619
  • Last Modified:

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 ?
0
comicboy
Asked:
comicboy
  • 3
  • 2
  • 2
  • +3
1 Solution
 
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
 
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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
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
 
MBoCommented:
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
 
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

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 3
  • 2
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now