core4096
core4096

Reputation: 111

Delphi - Text from file in ZIP to Memo

In some ZIP file I have file head.txt. I want to copy text from this file to TMemo on my form. Here's my code:

procedure TformMain.LoadProject(InputFileName: string);
var
  MS: TMemoryStream;
  zip: TZipForge;
  txt: string;
begin
  MS := TMemoryStream.Create;
  try
    zip := TZipForge.Create(nil);
    try
      with zip do begin
        FileName := InputFileName;
        OpenArchive(fmOpenReadWrite);
        ExtractToStream('head.txt', MS);
        CloseArchive;
      end;
    finally
      zip.Free;
    end;
    MS.Seek(0, soFromBeginning);
    SetLength(txt, MS.Size);
    MS.Write(txt[1], MS.Size);
  finally
    MS.Free;
  end;
  if Length(txt) > 0 then Memo1.Lines.Text := txt;
end;

But it doesn't work. In head.txt in my ZIP file is:

123456
abcdef
xxxx

and the result in Memo is:

auto-suggest dropdow

Thanks for help!

Upvotes: -2

Views: 1134

Answers (2)

nepb
nepb

Reputation: 199

Try replacing this code:

MS.Seek(0, soFromBeginning);
SetLength(txt, MS.Size);
MS.Write(txt[1], MS.Size);

with a call to SetString

SetString(txt, PAnsiChar(MS.Memory), MS.Size);

like in this question

Upvotes: 2

SilverWarior
SilverWarior

Reputation: 8386

The problem is that instead of reading data from Memory Stream into your txt variable using Read method you are actually writing data from your txt variable into your Memory Stream.

So your code should look more like this

procedure TformMain.LoadProject(InputFileName: string);
var
  MS: TMemoryStream;
  zip: TZipForge;
  txt: string;
begin
  MS := TMemoryStream.Create;
  try
    zip := TZipForge.Create(nil);
    try
      with zip do begin
        FileName := InputFileName;
        OpenArchive(fmOpenReadWrite);
        ExtractToStream('head.txt', MS);
        CloseArchive;
      end;
    finally
      zip.Free;
    end;
    MS.Seek(0, soFromBeginning);
    SetLength(txt, MS.Size);
    MS.Read(txt, MS.Size);
  finally
    MS.Free;
  end;
  if Length(txt) > 0 then Memo1.Lines.Text := txt;
end;

I haven't tested it out.

But since you want to load the text from that file into Memo you could simplify this by removing the txt variable and all the fuss needed with it and load the text into memo directly from the memory stream like this:

Memo1.Lines.LoadFromStream(MS);

So your final code should look like this:

procedure TformMain.LoadProject(InputFileName: string);
var
  MS: TMemoryStream;
  zip: TZipForge;
begin
  MS := TMemoryStream.Create;
  try
    zip := TZipForge.Create(nil);
    try
      with zip do begin
        FileName := InputFileName;
        OpenArchive(fmOpenReadWrite);
        ExtractToStream('head.txt', MS);
        CloseArchive;
      end;
    finally
      zip.Free;
    end;
    MS.Seek(0, soFromBeginning);
    Memo1.Lines.LoadFromStream(MS);
  finally
    MS.Free;
  end;
end;

Upvotes: 4

Related Questions