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

简介:
 
手上的一个VB项目(过程中发现,.Net果然是好啊),需要在一个ActiveX中实现HTTP下载功能,我是采用InternetreadFile这个API来实现,一开始的代码我是这么写的
 
None.gif Function  Gethttpdownload(sUrl  As   String As  boolen
None.gif 
None.gif
Dim  s  As   String
None.gif
Dim  hOpen  As   Long
None.gif
Dim  hOpenUrl  As   Long
None.gif
Dim  bDoLoop  As   Boolean
None.gif
Dim  bRet  As   Boolean
None.gif
Dim  sReadBuffer  As   String   *   2048
None.gif
Dim  lNumberOfBytesRead  As   Long
None.gifhOpen 
=  InternetOpen(scUserAgent, INTERNET_OPEN_TYPE_PRECONFIG, vbNullString, vbNullString,  0 )
None.gifhOpenUrl 
=  InternetOpenUrl(hOpen, sUrl, vbNullString,  0 , INTERNET_FLAG_RELOAD,  0 )
None.gif bDoLoop 
=   True
None.gif 
Do   While  bDoLoop
None.gif  sReadBuffer 
=  vbNullString
None.gif  bRet 
=  InternetReadFile(hOpenUrl, sReadBuffer,  Len (sReadBuffer), lNumberOfBytesRead)
None.gif  s 
=  s  &   Left $(sReadBuffer, lNumberOfBytesRead)
None.gif  
If   Not   CBool (lNumberOfBytesRead)  Then  bDoLoop  =   False
None.gif  
Loop
None.gifFileName 
=   " E:\BitSpirit\Torrent\121212.torrent"
None.gif
F1  =  FreeFile
None.gifOpen FileName 
For  Binary  As  F1
None.gifPut F1, , s
None.gifClose F1
None.gif 
If  hOpen  <>   0   Then  InternetCloseHandle (hOpen)
None.gif Gethttpdownload 
=   true
None.gif 
End Function
None.gif
 
上面方法,用来获取服务器上的文本类型的文件一点问题,都没有,但是用来下载二进制文件的时候 就出现问题了,里面的数据怎么也不对,研究了下载下来的文件后发现,问题外话应该是在接收数据的变量是个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的定义)最后完整的函数
None.gif Function  FileDownload(sUrl  As  Variant)  As   Boolean
None.gif        
Dim  b( 99 As   Byte
None.gif        
Dim  EndByte()  As   Byte
None.gif        
Dim  s  As   String
None.gif        
Dim  hOpen  As   Long
None.gif        
Dim  hOpenUrl  As   Long
None.gif        
Dim  bDoLoop  As   Boolean
None.gif        
Dim  bRet  As   Boolean
None.gif        
Dim  bbuffer  As   Byte
None.gif        
Dim  sReadBuffer  As   String
None.gif        
Dim  FileName  As   String
None.gif        
Dim  lNumberOfBytesRead  As   Long
None.gif        
Dim  F1  As   Integer
None.gif        
Dim  strsize  As   String
None.gif        
Dim  size  As   Long
None.gif        strsize 
=   String $( 1024 "   " )
None.gif 
None.gif        F1 
=  FreeFile
None.gif        stTotal 
=  vbNullString
None.gif        FileName 
=   " E:\BitSpirit\Torrent\121212.torrent"
None.gif
        Open FileName  For  Binary  As  F1
None.gif        hOpen 
=  InternetOpen(scUserAgent, INTERNET_OPEN_TYPE_PRECONFIG, vbNullString, vbNullString,  0 )
None.gif        hOpenUrl 
=  InternetOpenUrl(hOpen, sUrl, vbNullString,  0 , INTERNET_FLAG_RELOAD,  0 )
None.gif        bDoLoop 
=   True
None.gif        HttpQueryInfo hOpenUrl, HTTP_QUERY_CONTENT_LENGTH 
Or  HTTP_QUERY_FLAG_NUMBER, ByVal strsize,  Len (strsize),  0
None.gif        size 
=   CLng ( Trim (strsize))
None.gif         
For  j  =   1   To  size  \   100
None.gif          bDoLoop 
=  InternetReadFileByte(hOpenUrl, b( 0 ),  100 , lNumberOfBytesRead)
None.gif 
None.gif          Put F1, , b
None.gif          
If   Not   CBool (lNumberOfBytesRead)  Then   Exit   For
None.gif         
Next
None.gif        
If  size  Mod   100   <>   0   Then
None.gif        tmp 
=  (size  Mod   100 -   1
None.gif        
ReDim  EndByte(tmp)
None.gif          bDoLoop 
=  InternetReadFileByte(hOpenUrl, EndByte( 0 ), tmp  +   1 , lNumberOfBytesRead)
None.gif          Put F1, , EndByte
None.gif        
End   If
None.gif 
None.gif         
If  hOpenUrl  <>   0   Then  InternetCloseHandle (hOpenUrl)
None.gif         
If  hOpen  <>   0   Then  InternetCloseHandle (hOpen)
None.gif 
None.gif        Close #
1
None.gif        FileDownload 
=   True
None.gif
End Function
None.gif
测试了一下,完全成功:)







    本文转自无心之柳.NET博客园博客,原文链接:http://www.cnblogs.com/9527/archive/2005/05/19/159108.html ,如需转载请自行联系原作者

相关文章
|
14天前
|
存储 C++ iOS开发
C++文件操作(文本文件的读写+二进制文件的读写)
C++文件操作(文本文件的读写+二进制文件的读写)
|
6月前
|
移动开发
二进制文件与文本文件的区别
二进制文件与文本文件的区别
C#编程-35:写入读取文本文件
C#编程-35:写入读取文本文件
|
iOS开发 C++
C++文件读写操作分析文本文件与二进制文件
文本文件 写文件 写文件步骤如下: 1. 包含头文件 #include <fstream> 2. 创建流对象 ofstream ofs; 3. 打开文件 ofs.open("文件路径",打开方式); 4. 写数据 ofs << "写入的数据"; 5. 关闭文件 ofs.close(); 文件打开方式: 打开方式 解释 ios::in 为读文件而打开文件 ios::out 为写文件而打开文件 ios::ate 初始位置:文件尾 ios::app 追加方式写文件 ios::trunc 如果文件存在先删除,再创建 ios::binary 二进制方式
342 0
C++文件读写操作分析文本文件与二进制文件
|
大数据 C#
C# 读取大文件 (可以读取3GB大小的txt文件)
原文:C# 读取大文件 (可以读取3GB大小的txt文件) 在处理大数据时,有可能 会碰到 超过3GB大小的文件,如果通过 记事本 或 NotePad++去打开它,会报错,读不到任何文件。
4113 1
|
C#
C#选择多个文件并读取多个文件数据
原文:C#选择多个文件并读取多个文件数据 版权声明:本文为博主原创文章,转载请附上链接地址。 https://blog.csdn.net/ld15102891672/article/details/80586097 ...
1465 0
|
C++ 存储 iOS开发