InternetReadFile如何正確讀取二進制文件

手上的一個VB項目(過程中發現,.Net果然是好啊),需要在一個ActiveX中實現HTTP下載功能,我是採用InternetreadFile這個API來實現,一開始的代碼我是這麼寫的
 
Function Gethttpdownload(sUrl As StringAs boolen
 
Dim s As String
Dim hOpen As Long
Dim hOpenUrl As Long
Dim bDoLoop As Boolean
Dim bRet As Boolean
Dim sReadBuffer As String * 2048
Dim lNumberOfBytesRead As Long
hOpen 
= InternetOpen(scUserAgent, INTERNET_OPEN_TYPE_PRECONFIG, vbNullString, vbNullString, 0)
hOpenUrl 
= InternetOpenUrl(hOpen, sUrl, vbNullString, 0, INTERNET_FLAG_RELOAD, 0)
 bDoLoop 
= True
 
Do While bDoLoop
  sReadBuffer 
= vbNullString
  bRet 
= InternetReadFile(hOpenUrl, sReadBuffer, Len(sReadBuffer), lNumberOfBytesRead)
  s 
= s & Left$(sReadBuffer, lNumberOfBytesRead)
  
If Not CBool(lNumberOfBytesRead) Then bDoLoop = False
  
Loop
FileName 
= "E:/BitSpirit/Torrent/121212.torrent"
F1 = FreeFile
Open FileName 
For Binary As F1
Put F1, , s
Close F1
 
If hOpen <> 0 Then InternetCloseHandle (hOpen)
 Gethttpdownload 
= true
 
End Function
 
上面方法,用來獲取服務器上的文本類型的文件一點問題,都沒有,但是用來下載二進制文件的時候 就出現問題了,裏面的數據怎麼也不對,研究了下載下來的文件後發現,問題外話應該是在接收數據的變量是個STRING的定長字符串上。但是在網上查了好 久,甚至M$ MSDN上的一個用VB來實現下載的程也是用 string類型來接收數據的而且網上的代碼寫法,基本上也都是這個樣,好來纔好現,都是從MSDN上的哪個例程上演變過來的.
       我想如果能用一個byte數組來代替定長字符串,哪可能就沒有問題了,但是查看了一個VB 對Internetreadfile的申明
Public Declare Function InternetReadFile Lib "wininet.dll" (ByVal hFile As Long, ByVal sBuffer As String, ByVal lNumBytesToRead As Long, lNumberOfBytesRead As Long) As Integer
發現其定義ByVal sBuffer As String 看來只能用String了,在網上查找過程中,發現人家用VC寫的 程序中這人蔘數可以是其它的,所以查看了一下Internetreadfile的原型。發現的確可以, 所以我把internetreadfile的定義修改了一下,爲了通用,我爲新的internetreadfile定義了一個別名。 Internetreadfilebyte申明如下:
Public Declare Function InternetReadFileByte Lib "wininet.dll" Alias "InternetReadFile" (ByVal hFile As Long, ByRef sBuffer As Byte, ByVal lNumBytesToRead As Long, lNumberOfBytesRead As Long) As Integer
試了一下的確可以,重新修改函數,(在這過程中發現,如果要取到正確數據,還必須取得文件大小。所以增加了HttpQueryInfo的定義)最後完整的函數
Function FileDownload(sUrl As Variant) As Boolean
        
Dim b(99As Byte
        
Dim EndByte() As Byte
        
Dim s As String
        
Dim hOpen As Long
        
Dim hOpenUrl As Long
        
Dim bDoLoop As Boolean
        
Dim bRet As Boolean
        
Dim bbuffer As Byte
        
Dim sReadBuffer As String
        
Dim FileName As String
        
Dim lNumberOfBytesRead As Long
        
Dim F1 As Integer
        
Dim strsize As String
        
Dim size As Long
        strsize 
= String$(1024" ")
 
        F1 
= FreeFile
        stTotal 
= vbNullString
        FileName 
= "E:/BitSpirit/Torrent/121212.torrent"
        Open FileName For Binary As F1
        hOpen 
= InternetOpen(scUserAgent, INTERNET_OPEN_TYPE_PRECONFIG, vbNullString, vbNullString, 0)
        hOpenUrl 
= InternetOpenUrl(hOpen, sUrl, vbNullString, 0, INTERNET_FLAG_RELOAD, 0)
        bDoLoop 
= True
        HttpQueryInfo hOpenUrl, HTTP_QUERY_CONTENT_LENGTH 
Or HTTP_QUERY_FLAG_NUMBER, ByVal strsize, Len(strsize), 0
        size 
= CLng(Trim(strsize))
         
For j = 1 To size / 100
          bDoLoop 
= InternetReadFileByte(hOpenUrl, b(0), 100, lNumberOfBytesRead)
 
          Put F1, , b
          
If Not CBool(lNumberOfBytesRead) Then Exit For
         
Next
        
If size Mod 100 <> 0 Then
        tmp 
= (size Mod 100- 1
        
ReDim EndByte(tmp)
          bDoLoop 
= InternetReadFileByte(hOpenUrl, EndByte(0), tmp + 1, lNumberOfBytesRead)
          Put F1, , EndByte
        
End If
 
         
If hOpenUrl <> 0 Then InternetCloseHandle (hOpenUrl)
         
If hOpen <> 0 Then InternetCloseHandle (hOpen)
 
        Close #
1
        FileDownload 
= True
End Function
測試了一下,完全成功:)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章