7

我正在使用 Indy (idHTTP) 从 Internet 下载 EXE 文件,我可以使用 memorystream 或 filestream 将其保存到磁盘,但我真的不知道它们之间是否有任何区别(可能在文件的结果结构中? )。我还没有找到答案。

在哪里,这里有 2 个简单的函数来模拟我在做什么:

Function DownloadMS(FUrl, Dest: String): Boolean;
var
  Http: TIdHTTP;
  Strm: TMemoryStream;
Begin
  Result := False;
  Http := TIdHTTP.Create;
  Strm := TMemoryStream.Create;
  With Http, Strm Do
  Try
    Try
      Get(FUrl, Strm);
      If (Size > 0) Then
      Begin
        Position := 0;
        SaveToFile(Dest);
        Result := True;
      end;
    Except
    end;
  Finally
    Strm.Free;
    Http.Free;
  end;
end;

Function DownloadFS(FUrl, Dest: String): Boolean;
var
  Http: TIdHTTP;
  Strm: TFileStream;
Begin
  Result := False;
  Http := TIdHTTP.Create;
  Strm := TFileStream.Create(Dest, fmCreate);
  With Http, Strm Do
  Try
    Try
      Get(FUrl, Strm);
      Result := (Size > 0);
    Except
    end;
  Finally
    Strm.Free;
    Http.Free;
  end;
end;

您的专家对使用一种或其他类型(内存流或文件流)有何看法?使用一种或其他类型时,EXE 文件的结构有什么不同吗?推荐什么类型?

谢谢!周末愉快!

4

2 回答 2

8

TMemoryStream从流的角度来看或TFileStream从流的角度来看没有区别。

它们都是流并保存字节流,并且都派生自TStream.

您可以像这样实现泛化的功能

function DownloadToStream( const AUrl : String; ADest : TStream ): Boolean;
var
  LHttp: TIdHTTP;
begin
  LHttp := TIdHTTP.Create;
  try
    LHttp.Get( AUrl, ADest );
    Result := ADest.Size > 0;
  finally
    LHttp.Free;
  end;
end;

并用TFileStream

var
  LStream : TStream;

begin
  LStream := TFileStream.Create( 'MyFile.exe', fmCreate );
  if DownloadToStream( '', LStream ) then
    ...
end;

TMemoryStream或您喜欢的任何流实例

于 2013-05-04T14:39:53.963 回答
2

在许多情况下,在下载和文件之间放置一个中间内存流是没有意义的。所有这一切都会消耗内存,因为您必须先将整个文件放入内存中,然后才能将其放入磁盘。直接使用文件流可以避免这个问题。

文件流选项有问题的主要情况是,如果您想确保在保存到磁盘之前已成功下载整个文件。例如,如果您要覆盖文件的先前版本,您可能想要下载它,检查哈希签名,然后才覆盖原始文件。在这种情况下,您需要在覆盖之前将文件放在某个临时位置。您可以使用内存流,也可以使用带有临时文件名的文件流。

于 2013-05-04T14:17:07.813 回答