手上的一個VB項目(過程中發現,.Net果然是好啊),需要在一個ActiveX中實現HTTP下載功能,我是採用InternetreadFile這個API來實現,一開始的代碼我是這麼寫的
Function Gethttpdownload(sUrl As String) As 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(99) As 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
![]()
測試了一下,完全成功:)