Solved

save two TStringList to FileStream

Posted on 2002-04-05
10
2,436 Views
Last Modified: 2008-02-01
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
Comment
Question by:comicboy
  • 3
  • 2
  • 2
  • +3
10 Comments
 

Author Comment

by:comicboy
ID: 6920782
Sorry for loading parameter is fmOpenRead instead of fmCreate sorry (I just copy it :p )
0
 

Expert Comment

by:classics
ID: 6920838
Save them to seperate files.
0
 
LVL 4

Expert Comment

by:nestorua
ID: 6921114
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
 

Author Comment

by:comicboy
ID: 6921332
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
 

Expert Comment

by:classics
ID: 6921522
Try using TInifile then, save each list under a different header (key).
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 4

Expert Comment

by:nestorua
ID: 6921606
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
 
LVL 1

Accepted Solution

by:
MBo earned 50 total points
ID: 6922364
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
 
LVL 10

Expert Comment

by:Jacco
ID: 6922519
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
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6922556
nice way with TReader and TWriter :)
0
 

Author Comment

by:comicboy
ID: 6922932
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
System restore point 4 91
Sending Gmail through Delphi 3 91
Working with hours 3 46
Graphics32 under Delphi 10.1 Berlin 2 38
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.
Both in life and business – not all partnerships are created equal. As the demand for cloud services increases, so do the number of self-proclaimed cloud partners. Asking the right questions up front in the partnership, will enable both parties …

867 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

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now