Delphi - 我可以将InternetReadFile用于本地文件吗?

时间:2013-01-11 09:32:37

标签: delphi file download local wininet

我需要使用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;

感谢所有信息,链接,文档,评论......

1 个答案:

答案 0 :(得分:2)

您不仅仅使用一些与互联网相关的功能。您使用HttpOpenRequest - HTTP。按名称,这只适用于HTTP或HTTP / SSL协议。它甚至不适用于其他互联网协议来获取FTP,BitTorrent,Gnutella等文件。

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

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

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

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

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