【问题标题】:Downloading a file in Delphi在 Delphi 中下载文件
【发布时间】:2011-03-31 04:38:08
【问题描述】:

谷歌搜索显示了一些关于如何在 Delphi 中下载文件的示例,但大多数都是错误的,而且根据我的经验,有一半的时间不起作用。

我正在寻找一个简单而强大的解决方案,它可以让我下载一个 exe(用于更新我的应用程序),并且会保持当前更新线程的执行,直到下载完成或出错。该进程已经线程化,因此下载代码应该一直执行到它完成(希望如此)。

这里有两个实现,看起来都很复杂
1.http://www.scalabium.com/faq/dct0116.htm
2.http://delphi.about.com/od/internetintranet/a/get_file_net.htm

【问题讨论】:

    标签: windows delphi winapi download


    【解决方案1】:

    为什么不使用 Indy?如果你使用TIdHTTP组件,很简单:

    procedure TMyForm.DownloadFile;    
    var
      IdHTTP1: TIdHTTP;
      Stream: TMemoryStream;
      Url, FileName: String;
    begin    
      Url := 'http://www.rejbrand.se';
      Filename := 'download.htm';
    
      IdHTTP1 := TIdHTTP.Create(Self);
      Stream := TMemoryStream.Create;
      try
        IdHTTP1.Get(Url, Stream);
        Stream.SaveToFile(FileName);
      finally
        Stream.Free;
        IdHTTP1.Free;
      end;
    end;
    

    您甚至可以使用OnWorkOnWorkBegin 事件添加进度条:

    procedure TMyForm.IdHTTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode;AWorkCountMax: Int64);
    begin
      ProgressBar.Max := AWorkCountMax;
      ProgressBar.Position := 0;
    end;
    
    procedure TMyForm.IdHTTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
    begin
      ProgressBar.Position := AWorkCount;
    end;
    
    procedure TMyForm.DownloadFile;    
    var
      IdHTTP1: TIdHTTP;
      Stream: TMemoryStream;
      Url, FileName: String;
    begin    
      Url := 'http://www.rejbrand.se';
      Filename := 'download.htm';
    
      IdHTTP1 := TIdHTTP.Create(Self);
      Stream := TMemoryStream.Create;
      try
        IdHTTP1.OnWorkBegin := IdHTTPWorkBegin;
        IdHTTP1.OnWork := IdHTTPWork;
        IdHTTP1.Get(Url, Stream);
        Stream.SaveToFile(FileName);
      finally
        Stream.Free;
        IdHTTP1.Free;
      end;
    end;
    

    我不确定这些事件是否在主线程的上下文中触发,因此对 VCL 组件所做的任何更新都可能必须使用 TIdNotify 组件来完成以避免线程问题。也许其他人可以检查一下。

    【讨论】:

    • 如果文件很大,您可能希望使用文件流而不是内存流。
    • 如果您的应用仅将网络用于更新过程 - 那么使用 Indy 会增加 .exe 大小。
    • 我该如何访问 IdHTTPWorkBegin 过程来修改它?
    • @Codex IdHTTPWorkBegin() 是您将编写然后分配给TIdHTTP.OnWork 事件的过程。我已经更新了答案以显示这一点。
    • @MikeTaylor "我不确定这些事件是否在主线程的上下文中触发" - 它们是在调用 TIdHTTP.Get() 的线程的上下文中触发的,所以是的,如果在工作线程中使用TIdHTTP,那么 UI 更新将必须与主线程同步。
    【解决方案2】:

    第二种方法是使用 WinINet(Windows API 的一部分)使用 Internet 资源的标准方法。我用过很多次,而且一直都很好用。我从未尝试过的第一种方法。 (两者都不是“非常复杂”。使用 Windows API 时总会有一些额外的步骤。)

    如果你想要一个非常简单的方法,你可以简单地调用UrlMon.URLDownloadToFile。您将无法(完全!)对下载进行任何精细控制,但它非常简单。

    例子:

    URLDownloadToFile(nil,
                      'http://www.rejbrand.se',
                      PChar(ExtractFilePath(Application.ExeName) + 'download.htm'),
                      0,
                      nil);
    

    【讨论】:

    • 提示:将Application.ExeName 替换为ParamStr(0) 以消除对Forms 单元的依赖。
    • @mjustin:是的。但是在生产代码中,您无论如何都不想将文件保存到应用程序的目录中,该目录是只读的(程序文件),除非程序是可移植的(例如在 USB 记忆棒上运行)。
    • 感谢安德烈亚斯的回答。我采用了我发布的第二种方法,因为你说这是标准,希望它是可靠的。感谢您的努力。
    • 感谢@AndreasRejbrand!这正是我想要的!
    • 记住这一点; Internet Explorer 下载历史记录不允许您下载正在下载的文件的最新版本.. 所以使用 IE api 可能更快,但不是在所有情况下下载文件的最佳方式..
    【解决方案3】:

    对于有更高版本的delphi的人,你可以使用这个:

    var
      http : TNetHTTPClient;
      url : string;
      stream: TMemoryStream;
    begin
      http := TNetHTTPClient.Create(nil);
      stream := TMemoryStream.Create;
      try
        url := YOUR_URL_TO_DOWNLOAD;
        http.Get(url, stream);
        stream.SaveToFile('D:\Temporary\1.zip');
      finally
        stream.Free;
        http.Free;
      end;
    end;
    

    【讨论】:

      【解决方案4】:

      使用 URLMon。

      errcode := URLMon.URLDownloadToFile(nil,
                            PChar('http://www.vbforums.com/showthread.php?345726-DELPHI-Download-Files'),
      PChar( 'a:\download.htm'),
            0,
            nil);
      if errcode > 0 then
            showmessage('Error while downloading: ' + inttostr(errcode));
      

      【讨论】:

      • 这基本上不是我八岁答案的副本吗? :)
      • 我不这么认为。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-23
      • 1970-01-01
      • 2011-09-07
      相关资源
      最近更新 更多