使用Flash技术通过Adobe AIR实现文件下载的断点续传

2013-3-14 雨辰 AS3

说到文件下载,就不能不说断点续传,大家可能用过在网页中借助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. 先发送一个下载请求,可以得到文件的真实尺寸 

    var getContentLengthRequest:URLRequest = new URLRequest(videoURL.text); 

    var getContentLengthLoader:URLLoader = new URLLoader(); 

    getContentLengthLoader.addEventListener(ProgressEvent.PROGRESS ,function(e:ProgressEvent):void { 

    contentLength = getContentLengthLoader.bytesTotal;//得到文件的真实尺寸 

    getContentLengthLoader.close();//停止下载 

    downloadByRange();//按照断点续传的方式下载 

    }); 

    getContentLengthLoader.load(getContentLengthRequest);

    复制代码
  2. 计算已下载的部分的字节长度 

    if(file.exists) {//如果文件是存在的,就说明下载过,需要计算从哪个点开始下载 

    fileStr.open(file, FileMode.READ); 

    startPoint = fileStr.bytesAvailable;//计算从哪个点开始下载 

    fileStr.close();//关闭文件流 

    }

    复制代码
  3. 为请求的Header添加Range 

    var rangeRequest:URLRequest = new URLRequest(videoURL.text); 

    var header:URLRequestHeader = new URLRequestHeader("Range", "bytes="+startPoint+"-"+endPoint);//注意这里很关键,我们在请求的Header里包含对Range的描述,这样服务器会返回文件的某个部分 

    rangeRequest.requestHeaders.push(header);//将头信息添加到请求里

    复制代码
  4. 保存文件 

    fileStr = new FileStream(); 

    fileStr.open(file, FileMode.UPDATE); 

    fileStr.position = fileStr.bytesAvailable;//将指针指向文件尾 

    fileStr.writeBytes(currentData, 0, currentData.length);//在文件中写入新下载的数据 

    fileStr.close();//关闭文件流

    复制代码

完整代码查看以及下载:

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

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

标签: AS3 -Flash

发表评论:

雨辰 joyimp|@2011-2018 京ICP备16030765号