我将从this answer 开始,而不是将输出结果放在字符串中,而是将缓冲区写入 TFileStream。
WinInet 非常好,因为它尊重用户在 Windows 上设置的代理设置(因此您不必花费大量工作来使用 Indy 进行配置)。
编辑:
我重构了这个答案以下载二进制文件。
由于它使用 WinInet,您可以将它用于 ftp 和 http 下载(是的,我检查过它确实如此)。
您可以扩展它以使用FtpFindFirstFile/InternetFindNextFile 并读取一大堆文件。
unit DownloadBinaryFileUnit;
interface
uses
Classes,
WinInet;
type
TWinInet = class
strict protected
class procedure ReadBinaryFileResponse(const UrlHandle: HINTERNET; const LocalFileName: string); static;
class procedure ReadResponse(const UrlHandle: HINTERNET; const ContentStream: TStream);
public
class procedure DownloadBinaryFile(const UserAgent, Url, LocalFileName: string); overload; static;
end;
implementation
uses
SysUtils,
Variants,
Windows,
IOUtils;
class procedure TWinInet.DownloadBinaryFile(const UserAgent, Url, LocalFileName: string);
var
InternetHandle: HINTERNET;
UrlHandle: HINTERNET;
begin
InternetHandle := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
try
UrlHandle := InternetOpenUrl(InternetHandle, PChar(Url), nil, 0, 0, 0);
try
ReadBinaryFileResponse(UrlHandle, LocalFileName);
finally
InternetCloseHandle(UrlHandle);
end;
finally
InternetCloseHandle(InternetHandle);
end;
end;
class procedure TWinInet.ReadBinaryFileResponse(const UrlHandle: HINTERNET; const LocalFileName: string);
var
ContentStream: TFileStream;
begin
ContentStream := TFile.Create(LocalFileName);
try
ReadResponse(UrlHandle, ContentStream);
finally
ContentStream.Free;
end;
end;
class procedure TWinInet.ReadResponse(const UrlHandle: HINTERNET; const ContentStream: TStream);
var
Buffer: array[0..1023] of Byte;
BytesRead: Cardinal;
begin
repeat
InternetReadFile(UrlHandle, @Buffer, SizeOf(Buffer), BytesRead);
ContentStream.Write(Buffer, BytesRead);
until BytesRead = 0;
end;
end.
--杰罗恩