0

我需要使用 WinInet 下载文件。

我想测试它,但是当我首先检查它时,它不适用于本地文件。(文件://*)

这是在没有互联网的情况下测试程序或在互联网消失时进行调试所必需的......

首先,我需要检查文件大小以了解 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;

感谢您提供的每一个信息、链接、文档、评论家...

4

1 回答 1

2

您不只是使用一些与互联网相关的功能。您使用即HttpOpenRequest-HTTP。顾名思义,这只适用于 HTTP 或 HTTP/SSL 协议。它甚至不应该适用于其他互联网协议来获取文件,如 FTP、BitTorrent、Gnutella 等。

file:// 是 URL 协议名称,它的确切含义是“不要上网,而是打开本地文件”,因此与互联网相关的功能可能无法正常工作。

当然,没有办法通过它发出 GET 或 HEAD 或其他仅限 HTTP 的命令。

更重要的是,它无法帮助您调试与 HTTP 相关的错误,因为要重现这些错误将需要重复正确的 HTTP 流量序列,有时甚至可能使用给定的远程服务器版本和配置。

安装一些本地 http 服务器,如 TinyWeb、nginx 或 lighttpd - 并进行调试。

Synapse 和 mORMot 库中还有 HTTP 服务器演示,因此您甚至可以制作自己的服务器进行调试。

于 2013-01-11T09:47:22.110 回答