赛迪网 > IT技术 编程语言 > 文章
  IT资讯搜索
 
IT产品搜索
[程序开发][网管世界][网络安全][数据库技术]
[操作系统][嘉宾聊天·在线访谈][活动集锦]
[精彩专题][Symantec专区][订阅IT技术周刊]
[开发论坛][网管论坛][安全论坛][数据库论坛]
[操作系统论坛][Sybase专区][IBM dW技术专区]
[病毒求助][病毒与漏洞播报][文档·源码下载]

用VB编写异步多线程下载程序

发布时间:2006.08.16 02:33     来源:plwww    作者:


作者:大庆油田有限公司勘探开发研究院网络室 满孝为了高效率地下载某站点的网页,我们可利用VB的Internet Transfer 控件编写自己的下载程序, Internet Transfer 控件支持超文本传输协议 (HTTP) 和文件传输协议 (FTP),使用 Internet Transfer 控件可以通过 OpenURL 或 Execute 方法连接到任何使用这两个协议的站点并检索文件。本程序使用多个Internet Transfer 控件,使其同时下载某站点。并可判断文件是否已下载过或下载过的文件是否比服务器上当前的文件陈旧,以决定是否重新下载。所有下载的文件中的链接都做了调整,以便于本地查阅。 
OpenURL 方法以同步方式传输数据。同步指的是传输操作未完成之前,不能执行其它过程。这样数据传输就必须在执行其它代码之前完成。 
而 Execute 方法以异步方式传输数据。在调用 Execute 方法时,传输操作与其它过程无关。这样,在调用 Execute 方法后,在后台接收数据的同时可执行其它代码。 
用 OpenURL 方法能够直接得到可保存到磁盘的数据流,或者直接在 TextBox 控件中阅览(如果数据是文本格式的)。而用 Execute 方法获取数据,则必须用 StateChanged 事件监视该控件的连接状态。当达到适当的状态时,调用 GetChunk 方法从控件的缓冲区获取数据。 
 
首先,建立启始的http检索连接, 
Public g As Variant 
Public k As Variant 
Public spath As String 
Dim links() As String 
g = 0 
spath = 本地保存下载文件的路径 
links(0)=启始URL 
inet1.execute links(0), "GET" '使用GET方法。 
 
事件监控子程序(每个Internet Transfer 控件设置相对应的事件监控子程序): 
用StateChanged 事件监视该控件的连接状态, 当该请求已经完成,并且所有数据均已接收到时,调用 GetChunk 方法从控件的缓冲区获取数据。 
Private Sub Inet1_StateChanged(ByVal State As Integer) 
'State = 12 时,使用 GetChunk 方法检索服务器的响应。 
Select Case State 
'...没有列举其它情况。 
 
Case icResponseCompleted '12 
'获取links(g)中的协议、主机和路径名。 
addsuf = Left(links(g), InStrRev(links(g), "/")) 
'获取links(g)中的文件名。 
fname = Right(links(g), Len(links(g)) - InStrRev(links(g), "/")) 
'判断是否是超文本文件,是超文本文件则分析其中的链接,若不是则存为二进制文件。 
If InStr(1, fname, "htm", vbTextCompare) = True Then 
'初始化用于保存文件的FileSystemObject对象。 
Set fs = CreateObject("Scripting.FileSystemObject") 
Dim vtData As Variant '数据变量。 
Dim strData As String: strData = "" 
Dim bDone As Boolean: bDone = False 
 
'取得第一块。 
vtData = inet1.GetChunk(1024, icString) 
DoEvents 
Do While Not bDone 
strData = strData & vtData 
DoEvents 
'取得下一块。 
vtData = inet1.GetChunk(1024, icString) 
If Len(vtData) = 0 Then 
bDone = True 
End If 
Loop 
 
'获取文档中的链接并置于数组中。 
Dim i As Variant 
Dim po1 As Variant 
Dim po2 As Variant 
Dim oril As String 
Dim newl As String 
Dim lmtime, ctime 
po1 = InStr(1, strData, "href=", vbTextCompare) + 5 
po2 = 1 
Dim newstr As String: newstr = "" 
Dim whostr As String: whostr = "" 
i = 0 
Do While po1 > 0 
newstr = Mid(strData, po2, po1) 
whostr = whostr + newstr 
po2 = InStr(po1, strData, ">", vbTextCompare) 
'将原链接改为新链接 
oril = Mid(strData, po1 + 1, po2 - po1 - 1) 
'如果有引号,去掉引号 
ln = Replace(oril, """", "", vbTextCompare) 
newl = Right(ln, Len(ln) - InStrRev(ln, "/")) 
whostr = whostr & newl 
If ln <> "" Then 
'判定文件是否下载过。 
If fileexists(spath & newl) = False Then 
links(i) = addsuf & ln 
i = i + 1 
Else 
lmtime = inet1.getheader("Last-modified") 
Set f = fs.getfile(spath & newl) 
ctime = f.datecreated 
'判断文件是否更新 
If DateDiff("s", lmtime, ctime) < 0 Then 
i = i + 1 
End If 
End If 
End If 
po1 = InStr(po2 + 1, strData, "href=", vbTextCompare) + 5 
Loop 
newstr = Mid(strData, po2) 
whostr = whostr + newstr 
 
Set a = fs.createtextfile(spath & fname, True) 
a.Write whostr 
a.Close 
k = i 
Else 
Dim vtData As Variant 
Dim b() As Byte 
Dim bDone As Boolean: bDone = False 
vtData = Inet2.GetChunk(1024, icByteArray) 
Do While Not bDone 
b() = b() & vtData 
vtData = Inet2.GetChunk(1024, icByteArray) 
If Len(vtData) = 0 Then 
bDone = True 
End If 
Loop 
Open spath & fname For Binary Access Write As #1 
Put #1, , b() 
Close #1 
End If 
Call devjob '调用线程调度子程序 
End Select 
 
End Sub 
 
Private Sub Inet2_StateChanged(ByVal State As Integer) 
... 
end sub 
 
... 
 
线程调度子程序,g和是k公用变量,k为最后一个链接的数组索引加一,g初值为零,每次加一,直到处理完最后一个链接。 
Private Sub devjob() 
 
If Not g + 1 < k Then GoTo reportline 
If Inet1.StillExecuting = False Then 
g = g + 1 
Inet1.Execute links(g), "GET" 
End If 
If Not g + 1 < k Then GoTo reportline 
If Inet2.StillExecuting = False Then 
g = g + 1 
Inet2.Execute links(g), "GET" 
End If 
 
... 
 
reportline: 
If Inet1.StillExecuting = False And Inet2.StillExecuting = False And ... Then 
MsgBox ("下载结束。") 
End If 
End Sub


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· Visual Basic 6中发送邮件的新方法 (01-27) · 用VB实现目录选择+浏览 (09-18)
· 符合Windows 98规范的帮助文件的开发 (09-07) · VBScript入门 (08-03)
· 如何通过VB获取网卡地址 (09-12) · VB中利用WinRAR进行文件压缩 (04-17)
· VB术语表 (01-14) · VB术语表 (03-13)
· VB编程的必备技巧 (02-20) · VB编程的必备技巧 (05-24)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
  赛迪推荐  
  手机·资费 ·新品·导购·评测·手机资费·宽带
手机搜索  诺基亚 N73 MOTO Z6
  IT产品 ·笔记本·台式机·服务器·打印·投影
IT产品搜索 
  IT技术 ·开发·网管·安全·数据库·操作系统
  信息化 ·热点·专题·访谈·周刊·方案案例
[政务][电信][金融][农业][制造业][中小企业]
[CIO][ERP][协同][IT管理][中间件][电子商务]
[政策][地方][专家][评估][辞典][博客][社区]
· 专题:一路畅通构想曲——让出行不再遭遇堵车
· CIO工作亲历:企业ERP选型不能忽视"选人关"
· 综述:信息化建设给中国监狱带来的各种变化
· 金融业风险管理和法规遵从有五点需考虑的因素
· 保险业CIO关注:该如何建立统一高效的CRM体系
· 调查显示:多数CIO对IT规划仍存在困惑和误解
  博客·论坛 ·曾剑秋·项立刚·Java学习·网管