3

我有这个基本上下载文件的delphi代码(使用Delphi 2010 + Indy 10.5.8 r4743),一切正常,除了当我下载100Mb(例如)时,似乎Indy分配了完整大小(即a立即创建包含 100MB 虚拟内容 (*) 的文件),然后下载该文件。

最后 100MB 被正确下载,但由于下载过程是在后台使用隐藏的 EXEecutable 完成的,我的代码依赖于临时文件大小来更新主 UI

with IdHTTP do
begin
     if FileExists(LocalFile) then
        iLength     := FileSize2(LocalFile)
     else
         iLength    := 0;

     DoExit         := False;
     try
        try
           repeat
                 if ExitApp then
                    Exit;

                 if Not FileExists(LocalFile) then
                    AFileStream     := TFileStream.Create(LocalFile, fmCreate)
                 else
                 begin
                      // File already exist, resume download
                      AFileStream   := TFileStream.Create(LocalFile, fmOpenReadWrite);
                      DoExit        := (AFileStream.Size >= iLength);
                      if (Not DoExit) then
                         AFileStream.Seek(Max(0, AFileStream.Size - 4096), soFromBeginning);
                 end;

                 iRangeEnd          := AFileStream.Size + 50000;

                 if (iRangeEnd < iLength) then
                    Request.Range   := IntToStr(AFileStream.Position) + '-' + IntToStr(iRangeEnd)
                 else
                 begin
                      Request.Range := IntToStr(AFileStream.Position) + '-';
                      DoExit        := True;
                 end;

                 PostTime           := Now;
                 Get(TheURL, AFileStream);
                 IsError            := Not (ResponseCode in [200, 206]);
           until DoExit;

           Disconnect;
        except
              IsError               := True;
        end;    // try/except
     finally
            FreeAndNil(AFileStream);
     end;    // try/finally
end;    // with

我的问题是有没有办法避免印地的这种行为?我知道我可以使用 OnWork 事件,但是我需要跟踪文件名。

理想情况下,我也想避免 IPC(有点矫枉过正+我不想使用它,比如说每秒进行多次下载,我非常喜欢使用文件大小作为下载进度的指示,因为它提供了更多的自由更新 UI 时)

(*) 我认为它是虚拟内容,因为我当前的互联网连接速度需要 60-100 秒才能真正获取文件

4

1 回答 1

5

是的,TIdHTTP如果它提前知道大小,则根据 HTTP 响应标头预先分配完整的文件大小。这是一种优化技术。预分配文件避免了写入较大文件时不必要的文件系统开销,因为文件不必随着时间的推移而不断增长,在 HDD 上寻找可用扇区,减慢写入过程。目前没有办法禁用预分配,这是 Indy 内部的硬编码行为。因此,依赖文件的实际大小作为进度指示器对您不起作用。您将不得不将实际进度信息从后台应用程序传达给主应用程序。

于 2012-05-15T17:08:27.523 回答