| 首页 | 新闻 | 网页 | 设计 | 色彩 | 原创 | 视觉 | 素材 | 动漫 | 酷站 | 策划 | 文案 | 访谈 | 运营 | 编程 | 数据库 | 服务器 | 下载 | 图库 | 
您的位置: 幽幽天空 > 网页 > 编程开发 > VB教程 > 文章正文 用户登录
用V2组件制作单选
连接SQL SERVER的
使用Visual Studi
一个自动生成用AD
VB访问SQLServer的
用VC程序来创建SQ
在 SQL Server 2K
VB程序中处理随机
VB编程的必备技巧
让VB应用程序支持

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

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

作者:佚名 来源:作者: 大庆油田有限公司勘探开发研究院网络室 满孝 更新:2006-8-25 21:05:35 错误报告 我要投稿
为了高效率地下载某站点的网页,我们可利用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
文章录入:skyuu    责任编辑:skyuu 
  • 上一篇文章:

  • 下一篇文章:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    发表评论:
    姓名:  评 分: 1分 2分 3分 4分 5分
     
  • 严禁发表危害国家安全、政治、黄色淫秽等内容的评论。
  • 用户需对自己在使用幽幽天空服务过程中的行为承担法律责任。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表机友个人观点,与本网站立场无关。