Adobe AIR实现文件下载的断点续传

说到文件下载,就不能不说断点续传,大家可能用过在网页中借助Flash来实现下载进度显示的工具,这个工具只适用于文件体积不是很大的时候,用户可以非常有保障的在一定的时间内下载完成,一旦下载进程中断(网络或其它原因),用户就不得不从头开始下载文件,这对于大文件体积的情况(比如视频),就会很麻烦,用户可能下载了几十MB的时候,突然网络断了,然后只能从头再来,这是非常差的体验。那么能否通过Flash技术,实现断点续传呢?我们先来探讨一下断点续传的原理。

断点续传的原理

现在基本上任何一个下载工具都是支持断点续传的,抛开P2P的成分不谈,我们单说通过HTTP服务器是如何实现断点续传的。关键在于你向HTTP服务器发起文件请求的时候,是否明确的告知,要下载文件的哪个区域,我们都知道HTTP请求是有一个Header的,实际上里面有个属性是定义下载的区域的,这个属性就是Range,它接收的值是一个区间范围,比如:

Range:bytes=0-10000

这样我们就可以按照一定的规则,将一个大文件拆分为若干很小的部分,然后分批次的下载,每个小块下载完成之后,都合并到文件中,这样即时中间中断了下载,我们重新开始下载的时候,也可以通过文件的字节长度来判断下载的起始点,然后重启断点续传的过程,直到最后完成下载过程。

在AS3中,我们是可以为URLRequest添加HTTP头的,就是URLRequestHeader。基于这一点,我们可以说,只需要Flash Player我们其实已经可以实现断点续传了,但问题在于Flash Player是不能自动保存本地文件的,也就是说我们整个断点续传的过程只能在内存里完成,一旦页面刷新,电脑重启,还是要从0开始下载,实际意义不大。

而AIR运行时的出现又为我们保存本地文件提供了可能,所以我们完全可以基于AS3+Flash Player+AIR,制作一个断点续传的工具。

实现过程

 实现的主要几个要点:

  1. 首先对文件发起请求,得到文件的尺寸(字节长度),但并不下载
  2. 然后将文件划分为若干区域,对第一个区域的内容发起请求(通过指定HTTP头的Range)
  3. 第一个区域的内容很快下载完成,使用File保存到本地文件
  4. 移动指针,对第二个区域的内容发起请求,下载完毕后与文件合并
  5. 以此类推,直到下载完成整个文件

主要代码片段:

  1. 先发送一个下载请求,可以得到文件的真实尺寸
        
        
    1. var getContentLengthRequest : URLRequest = new URLRequest (videoURL. text );
    2. var getContentLengthLoader : URLLoader = new URLLoader ( );
    3. getContentLengthLoader. addEventListener ( ProgressEvent. PROGRESS , function (e : ProgressEvent ) : void {
    4. contentLength = getContentLengthLoader. bytesTotal; //得到文件的真实尺寸
    5. getContentLengthLoader. close ( ); //停止下载
    6. downloadByRange ( ); //按照断点续传的方式下载
    7. } );
    8. getContentLengthLoader. load (getContentLengthRequest );
  2. 计算已下载的部分的字节长度
        
        
    1. if (file.exists ) { //如果文件是存在的,就说明下载过,需要计算从哪个点开始下载
    2. fileStr. open (file, FileMode.READ );
    3. startPoint = fileStr. bytesAvailable; //计算从哪个点开始下载
    4. fileStr. close ( ); //关闭文件流
    5. }
  3. 为请求的Header添加Range
        
        
    1. var rangeRequest : URLRequest = new URLRequest (videoURL. text );
    2. var header : URLRequestHeader = new URLRequestHeader ( "Range", "bytes=" +startPoint + "-" +endPoint ); //注意这里很关键,我们在请求的Header里包含对Range的描述,这样服务器会返回文件的某个部分
    3. rangeRequest. requestHeaders. push (header ); //将头信息添加到请求里
  4. 保存文件
        
        
    1. fileStr = new FileStream ( );
    2. fileStr. open (file, FileMode.UPDATE );
    3. fileStr. position = fileStr. bytesAvailable; //将指针指向文件尾
    4. fileStr. writeBytes (currentData, 0, currentData. length ); //在文件中写入新下载的数据
    5. fileStr. close ( ); //关闭文件流

完整代码查看以及下载:

http://www.riameeting.com/examples/end_point_download/

然后测试,你可以看到下载进度,也可以在下载的过程中点击暂停,甚至关闭应用,重新启动,都可以从断点开始下载文件

你可能感兴趣的:(应用服务器,网络应用,Flash,Adobe,AIR)