从Internet下载文件,同时可以随时中止下载

Ste*_*eve 7 delphi multithreading wininet download delphi-7

我想从专门用于下载的单独线程中下载Delphi程序中的文件.

问题是主程序可以随时关闭(因此下载线程也可以随时终止).因此,即使没有连接或服务器滞后宝贵的秒钟,我需要一种方法在一两秒内终止下载线程.

你们建议使用什么功能?

我已经尝试过InterOpenURL/InternetReadFile但它没有超时参数.它有一个异步版本,但我找不到任何有用的Delphi示例,我不确定异步版本是否会保护我免受挂起...

以前建议使用套接字,但TClientSocket似乎也没有超时功能.

我需要做好充分准备,如果用户在他/她的计算机上遇到Internet连接问题或者网络服务器一直滞后我的应用程序在关闭之前就不会挂起.

在回答我不想使用任何第三方组件和Indy时请记住.非常感谢任何示例代码.

谢谢!

And*_*and 5

这有效.

var
  DownloadAbort: boolean;

procedure Download(const URL, FileName: string);
var
  hInet: HINTERNET;
  hURL: HINTERNET;
  Buffer: array[0..1023] of AnsiChar;
  BufferLen, amt: cardinal;
  f: file;
const
  UserAgent = 'Delphi Application'; // Change to whatever you wish
begin
  DownloadAbort := false;
  hInet := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  try
    hURL := InternetOpenUrl(hInet, PChar(URL), nil, 0, 0, 0);
    try
      FileMode := fmOpenWrite;
      AssignFile(f, FileName);
      try
        Rewrite(f, 1);
        repeat
          InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen);
          BlockWrite(f, Buffer[0], BufferLen, amt);
          if DownloadAbort then
            Exit;
        until BufferLen = 0;
      finally
        CloseFile(f);
      end;
    finally
      InternetCloseHandle(hURL);
    end;
  finally
    InternetCloseHandle(hInet);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

实际上,上面的代码将是你的线程Execute方法的一部分,你不需要DownloadAbort; 你检查一下

if Terminated then
  Exit;
Run Code Online (Sandbox Code Playgroud)

  • @Steve:如果你要关闭应用程序,内存泄漏并不重要.操作系统将回收内存. (2认同)

Gra*_*erB 2

TWinSocketStream有超时。您基本上创建一个阻塞套接字,然后使用该套接字创建一个 TWinSocketStream 进行读/写。(有点像使用 StreamWriter)。然后循环直到连接关闭、线程终止或达到预期的字节数。有一个 WaitForData() 允许您检查传入的数据是否有超时,因此您永远不会“锁定”超过该超时值。

不过,您必须自己处理 http 进程。即,发送“GET”,然后读取响应标头以确定需要多少字节,但这并不太困难。