2013-01-11 18 views
0

我需要使用WinInet下載文件。德爾福 - 我可以使用InternetReadFile本地文件?

我想測試它,但由於我先檢查它,它不適用於本地文件。 (文件:// *)

這是必要的測試程序沒有互聯網,或調試上網的時候走了......

首先,我需要檢查與進步的HTTPRequest文件的大小,和未來我需要下載文件...

當我看到沒有這些功能與本地文件...

但是,也許我錯過了一些選項,或者我用錯了網址...如.. 。

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; 

感謝每一個信息,鏈接,文檔,評論家...

+0

如果您需要調試它 - 那麼只需安裝一些簡單的http服務器。畢竟,如果你在與HTTP相關的代碼中犯了錯誤,你將無法用非HTTP協議(如fopen)進行調試。有很多很小的HTTP服務器 - 只是使用它們。例如:http://www.ritlabs.com/en/products/tinyweb/ –

回答

2

你不使用只是一些互聯網相關的功能。您使用即HttpOpenRequest - HTTP。通過它的名字,這隻能用於HTTP或HTTP/SSL協議。它甚至不應該用於其他互聯網協議來獲取FTP,BitTorrent,Gnutella等文件。

file://是URL協議名稱,它的意思是「不要上網,打開本地文件」,因此與網絡相關的功能可能無法工作。

當然,沒有辦法通過它發出GET或HEAD或其他HTTP-only命令。

更何況,它不會幫助您調試與HTTP相關的錯誤,因爲那些重現的錯誤會嚴格要求重複HTTP流量順序,甚至有時甚至可能使用給定的遠程服務器版本和配置。

安裝一些像TinyWeb,nginx或lighttpd這樣的本地http服務器 - 並進行調試。

Synapse和mORMot庫中還有HTTP服務器演示,因此您甚至可以製作自己的服務器進行調試。