0

ファイルのダウンロードには WinInet を使用する必要があります。

テストしたいのですが、最初に確認したように、ローカル ファイルでは機能しません。(ファイル://*)

これは、インターネットなしでプログラムをテストしたり、インターネットがなくなったときにデバッグしたりするために必要です...

まず、HTTPRequest の進行状況についてファイル サイズを確認する必要があり、次にファイルをダウンロードする必要があります...

私が見たように、これらの機能はどれもローカルファイルで動作していません...

しかし、おそらく私はいくつかのオプションを逃したか、間違ったURLを使用しました...のように...

file://localhost/C:/temp/AV.GIF

誰もそれについて知っていますか:これらの関数をローカル ファイルに使用できますか? 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;

すべての情報、リンク、ドキュメント、批評家に感謝します...

4

1 に答える 1

2

インターネット関連の機能だけを使用していません。つまり、HttpOpenRequestHTTPを使用します。その名前では、これは HTTP またはおそらく HTTP/SSL プロトコルでのみ機能します。FTP、BitTorrent、Gnutella などの他のインターネット プロトコルでファイルを取得することさえできません。

file:// は URL プロトコル名であり、「インターネットに接続せず、代わりにローカル ファイルを開く」ことを意味するため、インターネット関連の機能はおそらく動作しません。

確かに、GET や HEAD などの HTTP のみのコマンドを発行する方法はありません。

さらに、HTTP 関連のバグをデバッグするのに役立つ方法はありません。それらのバグを再現するには、おそらく特定のリモート サーバーのバージョンと構成であっても、正確に HTTP トラフィック シーケンスを繰り返す必要があるからです。

TinyWeb、nginx、lighttpd などのローカル http サーバーをインストールし、デバッグを行います。

Synapse および mORMot ライブラリには HTTP サーバーのデモもあったため、デバッグ用に独自のサーバーを作成することもできます。

于 2013-01-11T09:47:22.110 に答える