读取 TZipFile 时发生内存泄漏

Sil*_*ver 1 delphi delphi-10.2-tokyo

以下代码创建一个.zip文件,其中包含名为HelloWord.txt. 后来,它正确地读取了文件,但是使用和释放时发生了内存泄漏procedure Zipfile.Read (0, LStream, ZHeader) LStream

我用来ReportMemoryLeaksOnShutdown := DebugHook <> 0;查看内存泄漏。

// Uses  System.zip, System.IOUtils;
    
procedure Probezip;
var
  zipfile           : TZipFile;
  PathDoc           : string;
  LStream           : TStream;
  ZHeader           : TZipHeader;
  MyList            : TStringList;
begin
  // (Path documents windows)
  PathDoc := TPath.GetDocumentsPath;

  zipfile := TZipFile.Create;
  MyList  := TStringList.Create;


try
 // Write test TZipfile
  MyList.Add ('Hello Word');
  MyList.SaveToFile (PathDoc + '\' + 'helloword.txt');

  zipfile.Open (PathDoc + '\' + 'test.zip', zmWrite);
  ZipFile.Add (PathDoc + '\' + 'helloword.txt');
  ZipFile.Close;
  MyList.Clear;

  // Read test Tzipfile
  zipfile.Open (PathDoc + '\' + 'test.zip', zmRead);
  LStream := TStream.Create; //This line should be removed to solve the
                               // problem as Andreas Rejbrand has pointed out.
                               // I leave it here as a didactic value.
   try
     zipfile.Read (0, LStream, ZHeader);
      MyList.LoadFromStream (LStream);
      Showmessage (MyList.Text); // Hello Word
    finally
      LStream.Free;
   end;
  finally
    zipfile.Close;
    zipfile.Free;
    MyList.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

And*_*and 6

您使用的重载的第二个参数TZipFile.Read是类型TStream但它是一个out参数

这意味着该TZipFile.Read方法创建一个流对象并LStream指向它。因此,您会泄漏之前在线路上手动创建的流。删除该行 ( LStream := TStream.Create;) 并向下移动try保护流:

zipfile.Read(0, LStream, ZHeader); // will CREATE a stream object
                                   // and save its address in LStream
try
  MyList.LoadFromStream(LStream);
  Showmessage(MyList.Text); // Hello Word
finally
  LStream.Free;
end;
Run Code Online (Sandbox Code Playgroud)