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

Delphi-我可以将InternetReadFile用于本地文件吗?,delphi,file,download,local,wininet,Delphi,File,Download,Local,Wininet,我需要使用WinInet下载文件 我想测试它,但当我首先检查它时,它对本地文件不起作用。 (文件://*) 这是需要测试的程序没有互联网,或调试时,互联网消失 首先,我需要用HTTPRequest检查文件大小的进度,然后我需要下载文件 正如我看到的,这些函数都不能处理本地文件 但也许我错过了一些选择,或者我使用了错误的url。。。像 file://localhost/C:/temp/AV.GIF 有人知道吗: A.我可以对本地文件使用这些函数吗? B如果答案是肯定的,那么我需要如何更改代码 此

我需要使用WinInet下载文件

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

这是需要测试的程序没有互联网,或调试时,互联网消失

首先,我需要用HTTPRequest检查文件大小的进度,然后我需要下载文件

正如我看到的,这些函数都不能处理本地文件

但也许我错过了一些选择,或者我使用了错误的url。。。像

file://localhost/C:/temp/AV.GIF
有人知道吗: A.我可以对本地文件使用这些函数吗? B如果答案是肯定的,那么我需要如何更改代码

此示例演示如何使用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;

感谢您提供的每一条信息、链接、文档、评论……

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

file://是URL协议名,它的确切意思是“不要上网,而是打开本地文件”,因此与internet相关的功能可能无法在其上工作

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

更重要的是,它无法帮助您调试与HTTP相关的错误,因为这些错误的重现将要求HTTP通信序列完全重复,甚至有时在给定的远程服务器版本和配置下也是如此

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


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

如果需要调试,只需安装一些简单的HTTP服务器即可。毕竟,如果您在HTTP相关代码中出错,您将无法使用非HTTP协议(如
fopen
)对其进行调试。有很多小型HTTP服务器——只要使用它们就可以了。例如: