返回列表 发帖

[原创] vbs“多线程”下载

本帖最后由 wankoilz 于 2013-5-12 11:46 编辑

昨天重新看了下《深入挖掘Windows脚本技术》(原文不知道是谁写的,网上到处都是)。
里面提到了vbs多线程下载,今天尝试写了一下。
话说还是闲来练手,初步实现了自己认为的“多线程”下载。(注意这里的引号,关于vbs与多线程请参考12楼链接)
为避免冗余,省了一些错误检查。我觉得没多大实际用途,有兴趣的兄弟一起学习讨论呗。欢迎大家指正:
'From bbs.bathome.net By wankoilz
url=InputBox("输入完整下载地址:")
threadCount=InputBox("输入线程数(不超过10吧,太多就累赘了):")
fileName=GetFileName(url)
filePath=GetFilePath(WScript.ScriptFullName)
Set ohttp=CreateObject("msxml2.serverxmlhttp")
Set ado=CreateObject("adodb.stream")
Set fso=CreateObject("scripting.filesystemobject")
ado.Type=1
ado.Mode=3
ado.Open
ohttp.open "Head",url,True
ohttp.send
Do While ohttp.readyState<>4
    WScript.Sleep 200
Loop
'获得文件大小
fileSize=ohttp.getResponseHeader("Content-Length")
ohttp.abort
'创建一个和下载文件同样大小的临时文件,供下面ado分段重写
fso.CreateTextFile(filePath&"TmpFile",True,False).Write(Space(fileSize))
ado.LoadFromFile(filePath&"TmpFile")
blockSize=Fix(fileSize/threadCount):remainderSize=fileSize-threadCount*blockSize
upbound=threadCount-1
'定义包含msxml2.xmlhttp对象的数组,·成员数量便是“线程”数
'直接 Dim 数组名(变量名) 是不行的,这里用Execute变通了一下
Execute("Dim arrHttp("&upbound&")")
For i=0 To UBound(arrHttp)
    startpos=i*blockSize
    endpos=(i+1)*blockSize-1
    If i=UBound(arrHttp) Then endpos=endpos+remainderSize
    Set arrHttp(i)=CreateObject("msxml2.xmlhttp")
    arrHttp(i).open "Get",url,True
    '分段下载
    arrHttp(i).setRequestHeader "Range","bytes="&startpos&"-"&endpos
    arrHttp(i).send
Next
Do
    WScript.Sleep 200
    For i=0 To UBound(arrHttp)
        If arrHttp(i).readystate=4 Then
            '每当一个“线程”下载完毕就将其写入临时文件的相应位置
            ado.Position=i*blockSize
            MsgBox "线程"&i&"下载完毕!"
            ado.Write arrHttp(i).responseBody
            arrHttp(i).abort
            complete=complete+1
        End If
    Next
    If complete=UBound(arrHttp)+1 Then Exit Do
    timeout=timeout+1
    If timeout=5*30 Then
        '根据文件大小设定
        MsgBox "30秒超时!"
        WScript.Quit
    End If
Loop
If fso.FileExists(filePath&fileName) Then fso.DeleteFile(filePath&fileName)
fso.DeleteFile(filePath&"TmpFile")
ado.SaveToFile(filePath&fileName)
MsgBox "文件下载完毕!"
Function GetFileName(url)
    arrTmp=Split(url,"/")
    GetFileName=arrTmp(UBound(arrTmp))
End Function
Function GetFilePath(fullname)
    arrTmp=Split(fullname,"\")
    For i=0 To UBound(arrTmp)-1
        GetFilePath=GetFilePath&arrTmp(i)&"\"
    Next
End FunctionCOPY
测试下载地址:
http://bbs.bathome.net/images/default/logo.gifCOPY

1、异步和多线程是不能划等号的,类似的还有中断、信号/消息等。

2、zzzevazzz的《深入挖掘Windows脚本技术》可谓曲高和寡,诞生到现在快10年,但个人感觉本论坛中能完全理解的应该不超过10人;初学者剪刀+胶水,一般人学到利用ie,高级的学到加密,能学到后面事件消费者的算得上大师了。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

看到这个NB的技术很高兴
不过也感到很悲哀,,,复制到粘贴板就被杀软拦截。。。报毒。。。
难以使用应用起来。。。。。
早年的文件下载代码也是如此。。。。

TOP

4楼的链接,2004年的

厉害啊

QQ 20147578

TOP

隐约记得ActiveX控件都是单线程模型?
powerbat 发表于 2013-4-30 19:29


COM有4种线程模型

ThreadingModel="Both" indicates that instances of the class can execute in either an MTA or an STA.

ThreadingModel="Free" indicates that instances of the class can execute only in an MTA.

ThreadingModel="Apartment" indicates that instances of the class can execute only in an STA.

ThreadingModel="Absent" implies that instances of the class can run only in the main STA or the first STA initialized in the process.

TOP

隐约记得ActiveX控件都是单线程模型?

TOP

TOP

回复 9# wankoilz


    看来楼主是不经常在单位或者学校干坏事的好孩子 ←_←

TOP

本帖最后由 wankoilz 于 2013-5-1 22:07 编辑

感谢指正,现在只能用手机,空了再改一下。
我认为同时发送多个下载请求,几个对象一起接收数据,这勉强能算是“多线程下载”吧。

已改正!

TOP

搞错了,我一直还以为false是异步,糗了……

TOP

本帖最后由 CrLf 于 2013-4-30 14:11 编辑

回复 7# Demon


    那个贴子里的代码关键部分有一句 "Get",url,True,赤果果的异步传输,至于能不能把异步传输和多线程简单对应起来,这就不晓得了,反正我是没观察到新进程产生,所以认为它是多线程。
    本贴嘛,没注意楼主用的是同步传输,但是看到 arrHttp(i).xxxx 的用法,大概思路也知道了,改成异步应该也是可行的吧?

TOP

回复  czjt1234


    我贴的那个链接确实是多线程啊
    多进程方案貌似不在本贴讨论范围内
CrLf 发表于 2013-4-30 13:03


如何证明是多线程?

TOP

简单看了一下代码,姑且不论异步请求是否真的是多线程,假设它是多线程好了,

问题在于楼主用的是同步请求,里面的“线程”是按照顺序执行的,根本没有多线程的效果。

TOP

回复 3# czjt1234


    我贴的那个链接确实是多线程啊
    多进程方案貌似不在本贴讨论范围内

TOP

《深入挖掘Windows脚本技术》是zzzevazzz写的

原文地址http://www.xfocus.net/articles/200411/752.html

作者博客http://hi.baidu.com/zzzevazzz/item/f694350395a9608a02ce1ba9

TOP

返回列表