Delphi函数比较两个TStream的内容?

Tri*_*enT 9 delphi compare stream delphi-xe

我需要比较两个TStream后代是否具有相同的内容.对我来说唯一有趣的结果是布尔值是/否.

我将编写一个简单的循环检查字节流内容的字节.

但我很好奇,要知道,如果有一个已经存在的功能.我没有找到任何内部DelphiXE或JCL/JVCL库.

当然,这两个流的大小相同!

小智 12

确切地说,正如Nickolay O.所说,你应该在块中读取你的流并使用CompareMem.这是一个例子(包括尺寸测试)......

function IsIdenticalStreams(Source, Destination: TStream): boolean;
const Block_Size = 4096;

var Buffer_1: array[0..Block_Size-1] of byte;
    Buffer_2: array[0..Block_Size-1] of byte;
    Buffer_Length: integer;

begin
  Result := False;

  if Source.Size <> Destination.Size then
    Exit;

  while Source.Position < Source.Size do
    begin
      Buffer_Length := Source.Read(Buffer_1, Block_Size);
      Destination.Read(Buffer_2, Block_Size);

      if not CompareMem(@Buffer_1, @Buffer_2, Buffer_Length) then
        Exit;
    end;

  Result := True;
end;
Run Code Online (Sandbox Code Playgroud)

  • 我不喜欢TMemoryStream,因为它需要有一个连续的内存块,这对大文件来说是一个灾难.也许这在dcc64中会很好,但在此之前它值得避免.此代码不起作用,因为它代表大小小于Block_Size的流,因为您将比较随机堆栈噪声. (4认同)

小智 8

daemon_x发布的IsIdenticalStreams函数非常出色 - 但需要一次调整才能正常工作.(Uwe Raabe已经解决了这个问题.)在开始循环之前重置流位置至关重要 - 或者如果在此函数之外已经访问了两个流,则此过程可能会返回错误的TRUE.

这是每次都有效的最终解决方案.我刚刚重命名该函数以适合我的命名约定.感谢daemon_x提供优雅的解决方案.

function StreamsAreIdentical(Stream1, Stream2: TStream): boolean;
const
  Block_Size = 4096;

var
  Buffer_1: array[0..Block_Size-1] of byte;
  Buffer_2: array[0..Block_Size-1] of byte;
  Buffer_Length: integer;

begin

  Result := False;

  if Stream1.Size <> Stream2.Size then exit;

  // These two added lines are critical for proper operation 
  Stream1.Position := 0;
  Stream2.Position := 0;

  while Stream1.Position < Stream1.Size do
  begin

    Buffer_Length := Stream1.Read(Buffer_1, Block_Size);
    Stream2.Read(Buffer_2, Block_Size);
    if not CompareMem(@Buffer_1, @Buffer_2, Buffer_Length) then exit;

  end;

  Result := True;

end;
Run Code Online (Sandbox Code Playgroud)


Nic*_*sky 5

没有这样的内置功能.我只能推荐一件事 - 不是逐字节读取,而是使用16-64k字节的块,这样会快得多.