Delphi - 我可以将 InternetReadFile 用于本地文件吗?
Posted
技术标签:
【中文标题】Delphi - 我可以将 InternetReadFile 用于本地文件吗?【英文标题】:Delphi - Can I use InternetReadFile for local file? 【发布时间】:2013-01-11 09:32:37 【问题描述】:我需要使用 WinInet 来下载文件。
我想测试它,但是当我首先检查它时,它不适用于本地文件。 (file://*)
这是在没有互联网的情况下测试程序所需要的,或者在互联网消失时进行调试......
首先我需要检查文件大小以了解 HTTPRequest 的进度,然后我需要下载文件...
正如我所见,这些函数都不适用于本地文件...
但也许我错过了一些选项,或者我使用了错误的网址...比如...
file://localhost/C:/temp/AV.GIF
有人知道吗: 一种。我可以将这些功能用于本地文件吗? 湾。如果答案是肯定的,那么我需要如何更改我的代码?
这个例子展示了我如何使用 WinInet:
function TDDWIToolObject.GetFileSize(out Size: Int64): boolean;
var
hInet: HINTERNET;
hConnect: HINTERNET;
hRequest : HINTERNET;
lpdwBufferLength: DWORD;
lpdwReserved : DWORD;
ServerName: string;
Resource: string;
FileSizeBuffer : array[0..32] of char;
SizeCard : Cardinal;
begin
ParseURL(Url, ServerName, Resource);
Result := False;
Size := 0;
hInet := InternetOpen(PChar(_UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if hInet=nil then begin
FErrorCode := GetLastError;
Exit;
end;
try
hConnect := InternetConnect(hInet, PChar(ServerName), INTERNET_DEFAULT_HTTP_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 0);
if hConnect=nil then begin
FErrorCode := GetLastError;
Exit;
end;
try
hRequest := HttpOpenRequest(hConnect, PChar('HEAD'), PChar(Resource), nil, nil, nil, 0, 0);
if hRequest = nil then begin
FErrorCode := GetLastError;
Exit;
end;
try
FillChar(FileSizeBuffer, SizeOf(FileSizeBuffer), #0);
lpdwBufferLength := SizeOf(FileSizeBuffer);
lpdwReserved :=0;
if not HttpSendRequest(hRequest, nil, 0, nil, 0) then begin
FErrorCode := GetLastError;
Exit;
end;
if not HttpQueryInfo(
hRequest,
HTTP_QUERY_CONTENT_LENGTH,
@FileSizeBuffer, lpdwBufferLength, lpdwReserved) then begin
FErrorCode:=GetLastError;
Exit;
end;
Size := StrToInt64(StrPas(FileSizeBuffer));
Result := True;
finally
InternetCloseHandle(hRequest);
end;
finally
InternetCloseHandle(hConnect);
end;
finally
InternetCloseHandle(hInet);
end;
end;
function TDDWIToolObject.DownloadFile;
var
hInet: HINTERNET;
hFile: HINTERNET;
pbuffer: Pointer;
bytesRead: DWORD;
Stm : TFileStream;
TotalBytes : Int64;
AbortIt : boolean;
begin
Result := False;
FErrorCode := -1;
FAborted := False;
hInet := InternetOpen(PChar(_UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if hInet = nil
then begin
FErrorCode := GetLastError;
Exit;
end;
try
hFile := InternetOpenURL(hInet, PChar(URL), PChar(FHeaders), Length(FHeaders), 0, 0);
if hFile = nil
then begin
FErrorCode := GetLastError;
Exit;
end;
try
Stm := TFileStream.Create(FN, fmCreate);
try
GetMem(pbuffer, FBufferSize);
try
TotalBytes := 0; AbortIt := False;
while (not FAborted) do begin
if not InternetReadFile(hFile, pbuffer, FBufferSize, bytesRead) then begin
FErrorCode := GetLastError;
Exit;
end;
if bytesRead > 0 then begin
Stm.WriteBuffer(pbuffer^, bytesRead);
if Assigned(FOnBytesArrived)
then begin
inc(TotalBytes, bytesRead);
FOnBytesArrived(Self, TotalBytes, AbortIt);
if AbortIt
then Abort;
end;
end else begin
break;
end;
end;
finally
FreeMem(pbuffer);
end;
if not FAborted
then Result := True;
finally
Stm.Free;
end;
finally
InternetCloseHandle(hFile);
end;
finally
InternetCloseHandle(hInet);
end;
end;
感谢您提供的所有信息、链接、文档、评论...
【问题讨论】:
如果你需要调试它——那么只需安装一些简单的 http 服务器。毕竟,如果您在与 HTTP 相关的代码中出错,您将无法使用像fopen
这样的非 HTTP 协议对其进行调试。有很多微型 HTTP 服务器 - 只需使用它们。例如:ritlabs.com/en/products/tinyweb
【参考方案1】:
您不只是使用一些与互联网相关的功能。您使用即HttpOpenRequest
- HTTP。顾名思义,这只适用于 HTTP 或 HTTP/SSL 协议。它甚至不应该适用于其他互联网协议来获取文件,如 FTP、BitTorrent、Gnutella 等。
file:// 是 URL 协议名称,它的确切含义是“不要上网,而是打开本地文件”,因此与互联网相关的功能可能无法正常工作。
当然没有办法通过它发出 GET 或 HEAD 或其他仅限 HTTP 的命令。
更重要的是,它无法帮助您调试与 HTTP 相关的错误,因为要重现这些错误将需要重复正确的 HTTP 流量序列,有时甚至可能使用给定的远程服务器版本和配置。
安装一些本地 http 服务器,如 TinyWeb、nginx 或 lighttpd - 并进行调试。
Synapse 和 mORMot 库中还有 HTTP 服务器演示,因此您甚至可以制作自己的服务器进行调试。
【讨论】:
以上是关于Delphi - 我可以将 InternetReadFile 用于本地文件吗?的主要内容,如果未能解决你的问题,请参考以下文章