[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

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

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

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

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

TOP

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

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

已改正!

TOP

返回列表