张洪举的书,我那次一口气买了四本。确实写得不错,有那种举一反三的感觉。学到了很多以前没有学到过的东西。
工欲善其事,必先利其器!
老大,
我在网上看到以下思路
转:行者孙
纯VF实现HTTP带进度条的多'线程'断点下载 最近写一个小东西,要求有在线更新功能,碰到这样的问题首先想到了Msxml2.XMLHTTP和ADODB.Stream,最后同步下载到是实现了,但却被异步下载难倒了,后来找了大量的VC、VB、ASP、.NET等代码来参考,但始终很难在VF上直接实现,后来又转想到了WIDOWS的WININET(Microsoft Internet Transfer Control )控件,大家知道inet也有同步和异步两种方式,我们常用的获得网页源码的方法如:
thisform.inet.openurl('www.163.com')这样我们就得到了163主页的源代码,同样thisform.inet.openurl('http://www.vfptop.com/download/ydgl.rar',1)
这样的话我们就获得了ydgl.rar文件的全部内容,再新建立一个文件把得到的内容写进去就算是把ydgl.rar这个文件下载下来了,但是这样做是一次性把整个文件的内容全部下载,没办法实现进度表达,所以我们要采用异步方式来获取,也就是inet.execute(url),知道了这些就可以写代码了:
实现进度显示的步骤:
1、首先获取被下载文件的大小
我们知道在访问一个URL的时候会首先返回一个HTTP头文件,这文件头里包含有被下载文件相关重要信息,如这样一个THHP头:
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Wed, 16 Aug 2006 09:20:34 GMT
Content-Type: application/octet-stream
Accept-Ranges: bytes
Last-Modified: Mon, 14 Aug 2006 01:50:10 GMT
ETag: "3ac82dfa43bfc61:dae"
Content-Length: 10248
这里的Content-Length头部分显示的就是我们要下载文件的大小,这个数值我们可以用
inet.getheader(‘Content-Length’)来获得。
inet.getheader(‘Content-Length’)&&返回文件大小,字符型。
2、按段下载数据
知道了文件的大小,接下来就是要一段一段的来获取文件的数据,比如已知一个文件的大小是10M(10*1024*1024bety),我们下载的时候每次按1024KB来下载,那么一共要下载10次才能下载完,如果我们把这10次下载的任务交给10个inet去完成,那就变成了‘多线程’下载了,当然这里的‘多线程’实际上是多任务下载不是真正的多线程。
inet.execute(url,'get',,’ Range: bytes=0-’)这句的意思是获取被下载文件的头部一直尾部的全部数据,也就是整个文件。
inet.execute(url,'get',,’ Range: bytes=1024-2101’)这句的意思是获取被下载文件的1024字节到2101字节的部数据。
这样我们就可以很好的给inet分配下载段了。
inet.execute()获取了数据后,我们再用inet.GetChunk(size,1)来从缓冲区获取数据,这里的size是指你要获得的字节数。
这样我们就可以一段一段的下载文件了,实现进度条显示就解决了
3、显示进度信息
进度信息基本上靠一个timer就能刷新下载剩余量、下载百分比、下载剩余时间等进度信息了,这里就不多说了。
4、一些需要注意的地方
a. 分段下载的过程是个循环下载的过程,但我们却不能用for或者do whil这样的循环去操作,因为下载每一断的时候都是有延时的,由于VF是单线程顺序执行代码,所以这样操作一般都会失败,那么我们就采用计数变量来不逐一循环激发inet.execute()和inet.GetChunk(),比如我们是分100段来下载文件,当计数变量<=100的情况下就循环激发,也就是inet.GetChunk()后再去激发inet.execute()然后inet.execute()又去激发inet.GetChunk(),达到100的时候我们再看下这时候文件是否全部下载完毕,如果没有那么再把剩下的数据补进去就行了。
b. inet.GetChunk()获取的数据类型是和文件数据类型一致的,所以我们直接fcraete()建立一个文件,然后把获得数据直接fwrite() 就可以了。
c. 一般最少用两个inet来操作会更方便点,一个是获取文件信息,一个是专门下载数据。当然你非要用一个也是可以的。
d. 每个inet执行结束后最好inet.objiect.cancel,因为有些被下载的文件不支持多线程下载。
e. 段点续载你可以象flashget等软件先建立一个自己的文件结构,等下载完毕后再还原文件,如果补这样的话,比如有和你上次没下载完的文件同名的文件就补会看作是自己没下载完的文件了,续载的时候先检查下已存在的同名文件是否是自己以前下载过的文件这种情况就可以避免了
可我写不出程序来,能帮忙简单写一个 示例,供初学者学习吗,谢了,你的c/s,我会关注学习