我想从 Internet 下载一个文件,InternetReadFile 乍一看似乎是一个很好且简单的解决方案。实际上,好得令人难以置信。确实,深入挖掘后,我开始发现它实际上存在很多问题。人们在使用这段代码时提示各种各样的问题。
可能会出现问题,因为:
- 应用程序暂时卡住,直到 HTTP 服务器响应
- 应用程序暂时卡住,因为 Internet 连接中断
- 应用程序锁定,因为 HTTP 服务器从不响应
- InternetOpen(我最近才发现)在应用程序生命周期内必须只调用一次
我找不到关于如何正确和稳健地使用它的完整示例。有没有人知道如何在单独的线程中实现它并超时?还有另一种从 Internet 上可靠地下载文件的简单方法。尽管我不想让像 Jedi 甚至 Indy 这样的大型库让我的生活复杂化。
function GetFileHTTP (const fileURL, FileName: String): boolean;
CONST
BufferSize = 1024;
VAR
hSession, hURL: HInternet;
Buffer: array[1..BufferSize] of Byte;
BufferLen: DWORD;
f: File;
sAppName: string;
begin
// result := false;
sAppName := ExtractFileName(Application.ExeName) ;
hSession := InternetOpen(PChar(sAppName), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0) ; { be aware that InternetOpen need only be called once in your application!!!!!!!!!!!!!! }
TRY
hURL := InternetOpenURL(hSession, PChar(fileURL), nil, 0, 0, 0) ;
TRY
AssignFile(f, FileName) ;
Rewrite(f, 1) ;
REPEAT
InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen);
BlockWrite(f, Buffer, BufferLen)
UNTIL BufferLen = 0;
CloseFile(f) ;
Result:= True;
FINALLY
InternetCloseHandle(hURL)
end
FINALLY
InternetCloseHandle(hSession)
END;
END;
编辑: 此功能检查互联网连接是否可用。它似乎也适用于 Win98。
{ Are we connected to the Internet? }
function IsConnectedToInternet: Boolean; { Call SHELL32.DLL for Win < Win98 otherwise call URL.dll }
var InetIsOffline: function(dwFlags: DWORD): BOOL; stdcall;
begin
Result:= FALSE;
if IsApiFunctionAvailable('URL.DLL', 'InetIsOffline', @InetIsOffline)
then Result:= NOT InetIsOffLine(0)
else
if IsApiFunctionAvailable('SHELL32.DLL', 'InetIsOffline', @InetIsOffline)
then Result:= NOT InetIsOffLine(0)
end;
我正在使用 Delphi 7。非常感谢。
编辑:
因为应用程序在第一次启动时挂起而失去客户是赔钱的完美秘诀。
编写依赖于 Microsoft 平台的代码是不好的。您永远不知道客户是否安装了 IE 版本 x.x。
将东西安装到用户的计算机中就像玩枪一样。这会适得其反。
(在这里查看更多相关信息:http://thesunstroke.blogspot.com/2010/06/programmig-like-there-is-no-ms-windows.html)
最佳答案
我基本上和你做的一样。对我来说,它工作得相当完美。
我的代码和你的代码之间的唯一区别是我有一个 INTERNET_FLAG_RELOAD 参数来强制从文件而不是缓存下载。您可以尝试一下,看看效果是否更好:
hURL := InternetOpenURL(hSession, PChar(fileURL), nil, 0, INTERNET_FLAG_RELOAD, 0) ;
下载前还要检查互联网连接。这样做:
dwConnectionTypes := INTERNET_CONNECTION_MODEM
+ INTERNET_CONNECTION_LAN
+ INTERNET_CONNECTION_PROXY;
InternetConnected := InternetGetConnectedState(@dwConnectionTypes, 0);
if InternetConnected then ...
关于windows - 如何通过 HTTP 从 Internet 检索文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3122306/