InternetReadFile如何正确读取二进制文件

手上的一个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
测试了一下,完全成功:)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`InternetReadFile`是WinINet库中的函数,用于从打开的Internet资源中读取数据。以下是`InternetReadFile`函数的基本用法: ```cpp #include <windows.h> #include <wininet.h> #include <iostream> #pragma comment(lib, "wininet.lib") int main() { HINTERNET hInternet = InternetOpen(L"HTTPGET", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); if (hInternet == NULL) { std::cout << "Failed to open internet." << std::endl; return 1; } HINTERNET hConnect = InternetOpenUrl(hInternet, L"http://www.example.com", NULL, 0, INTERNET_FLAG_RELOAD, 0); if (hConnect == NULL) { std::cout << "Failed to open URL." << std::endl; InternetCloseHandle(hInternet); return 1; } char buffer[4096]; DWORD bytesRead = 0; while (InternetReadFile(hConnect, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) { // 在这里处理读取到的数据 std::cout.write(buffer, bytesRead); } InternetCloseHandle(hConnect); InternetCloseHandle(hInternet); return 0; } ``` 在这个示例代码中,我们使用`InternetOpen`函数打开一个Internet会话,然后使用`InternetOpenUrl`函数打开指定URL的连接。请将`http://www.example.com`替换为你想要请求的URL。 然后,我们使用`InternetReadFile`函数循环读取连接中的数据。在每次调用`InternetReadFile`后,我们检查`bytesRead`变量来确定是否成功读取数据,并在循环中处理读取到的数据。在这个示例中,我们简单地将数据写入到标准输出。 请注意,示例代码中的错误处理部分被简化了,实际应用中可能需要更完善的错误处理。 希望这个示例代码可以帮助你使用`InternetReadFile`函数从Internet资源中读取数据。如果有任何进一步的问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值