更新数据原理,访问接口,将服务器数据抓取并下载到本地的临时文件夹,当所有下载完成,卸载客户端内容,出现升级界面,此时移动下载的内容到目标文件夹,移动完成再重新加载客户端,访问接口,下载文件,移动文件均是队列完成。

根据实际接口操作可替换源代码中的必要代码,以下是源码:

DownloadControl.as

package com.controls
{
import com.controls.download.ConnectionUtil;
import com.controls.download.DownloadFile;
import com.controls.download.FileManager;
import com.models.Config;
import com.models.events.AppEvent;
import com.models.events.AppEventDispatcher; import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.URLVariables;
import flash.utils.ByteArray; /**
* @author Frost.Yen
* @E-mail 871979853@qq.com
* @create 2017-2-20 下午4:19:33
*
*/
public class DownloadControl
{
/**
* 下载资源的计数器
*/
private var _count:uint;
/**
* 第一级接口个数计数器
*/
private var _firstCount:int;
/**
* 第二级接口个数计数器
*/
private var _secondCount:int;
/**
* 第一级接口返回的数据,供第二级接口递归调用
*/
private var _datas:Object; private static var _instance:DownloadControl;
public function DownloadControl(s:S)
{
}
public static function getInstance():DownloadControl
{
if(!_instance){
_instance = new DownloadControl(new S());
}
return _instance;
}
public function reset():void
{
_count = 0;
_firstCount = 0;
_secondCount = 0;
_datas = null;
Config.downloadData = [];
}
/**
* 一级接口请求
*/
public function connection1():void
{
var connection:ConnectionUtil = new ConnectionUtil();
connection.connect(Config.connection+Config.config.link.item[_firstCount].@typeLink,Config.config.link.item[_firstCount].@name+".json","",null,onConnectComplete);
}
/**
* 二级接口请求
*/
private function connection2(datas:Object):void
{
var total:int = datas["data"]["response"].length;
var variables:URLVariables = new URLVariables();
variables.parameter = datas["data"]["response"][_secondCount]["id"];
var connection:ConnectionUtil = new ConnectionUtil();
connection.connect(Config.connection+Config.config.link.item[_firstCount].@contentLink,Config.config.link.item[_firstCount]+"_"+_secondCount+".json","",variables,onConnectComplete1); function onConnectComplete1(data:Object):void
{ for(var i:int = 0;i<data["data"]["response"].length;i++){
if(data["data"]["response"][i]["videoUrl"]){
var label:String = "videoUrl";
}
if(data["data"]["response"][i]["imgUrl"]){
label = "imgUrl";
}
var len:int = data["data"]["response"][i][label].length;
for(var j:int = 0;j<len;j++){//存储下载的文件名称
Config.downloadData.push(data["data"]["response"][i][label][j]["openFile"]);
if(label == "videoUrl"){
Config.downloadData.push(data["data"]["response"][i][label][j]["vframe"]);
}
} }
Config.jsonArr[_firstCount][_secondCount]["second"] = data["data"]["response"];//二级菜单保存
_secondCount++;
trace("------>>"+_secondCount+"------"+total+"--\n");
if(_secondCount >= total){
_firstCount++;
if(_firstCount>Config.config.link.item.length()-1){
//所有接口请求完成,将json保存到本地
var file:File = new File(Config.jsonPath+"data.json");
var fs:FileStream = new FileStream();
fs.open(file,FileMode.WRITE);
fs.writeBytes(getByteArr(JSON.stringify(Config.jsonArr)));
fs.close();
file = null;
fs = null;
//所有接口请求完成,开始下载
trace("------>>所有接口请求完成,开始下载---资源共:"+Config.downloadData.length+"个-----\n");
startDownload();
}else{
connection1();
} }else{
connection2(_datas);
}
}
}
private function onConnectComplete(data:Object):void
{ trace(JSON.stringify(data));
_datas = data;
_secondCount=0;
Config.jsonArr[_firstCount] = data["data"]["response"];//一级菜单保存
connection2(data);
}
/**
* 开始下载
* @param isAll true表示所有资源同时下载 false表示资源队列下载
*/
private function startDownload(isAll:Boolean=true):void
{
if(isAll){
for(var i:int = 0;i<Config.downloadData.length;i++){
download(i);
}
}else{
download(_count);
} function download(i:int):void
{
new DownloadFile().download(Config.source,Config.downloadData[i],Config.tempPath,Config.assets,onDownloaded);
}
function onDownloaded():void
{
trace("------>>第"+_count+"个资源下载完成\n");
_count++;
if(_count == Config.downloadData.length){//Config.downloadData.length
trace("------>>所有资源下载完成--------");
var tempList:Array = new File(Config.tempPath).getDirectoryListing();
AppEventDispatcher.getInstance().dispatchEvent(new AppEvent(AppEvent.DOWNLOAD_COMPLETE,tempList.length)); }else{
if(!isAll){
download(_count);
}
}
}
}
public function startMove():void
{
FileManager.deleteFilesByNotSame(Config.downloadData,Config.assets);
FileManager.startMoveFiles(File.applicationDirectory.nativePath+"/source/",Config.assets,onMoveComplete);
}
private function onMoveComplete():void
{
trace("------>>所有资源移动完成--------\n"); AppEventDispatcher.getInstance().dispatchEvent(new AppEvent(AppEvent.UPDATE_COMPLETE));
}
/**
* 将String转换成ByteArray类型
* @param param 被转换的String
* @return ByteArray 转换后的ByteArray
*
*/
private function getByteArr(param:String):ByteArray
{
var bytes:ByteArray = new ByteArray;
bytes.writeUTFBytes(param);
return bytes;
}
}
}
class S{ }

接口连接工具类 ConnectionUtil.as

package com.controls.download
{ import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import flash.utils.ByteArray; /**
* 连接接口工具类
* @author Frost.Yen
* @E-mail 871979853@qq.com
* @create 2017-2-16 下午2:50:58
*
*/
public class ConnectionUtil extends EventDispatcher
{
private var _ldr:URLLoader;
/**
* 将返回数据写入到本地,此为本地存储路径
*/
private var _localPath:String;
/**
* 将返回数据写入到本地,此为文件名称
*/
private var _fileName:String;
/**
* 接口连接地址
*/
private var _connectionURL:String;
/**
* 接口所需参数
*/
private var _argument:String;
/**
* 从接口获取的数据
*/
public var data:Object;
/**
* 接口连接成功,获取数据后回调函数
*/
public var onConnectSucceed:Function=null;
public function ConnectionUtil()
{
_ldr = new URLLoader();
_ldr.addEventListener(Event.COMPLETE,onConnectComplete);
_ldr.addEventListener(IOErrorEvent.IO_ERROR,onError);
} /**
* 连接接口成功
*/
private function onConnectComplete(e:Event):void
{
var str:String = e.target.data;
data = JSON.parse(str); trace("\n<<----------------- aticon: "+_connectionURL+" ----------------- argument: "+_argument+" -------------------------->>\nresult: \n"+str);
if(data.code == "200"){ //将json写入本地
/*var file:File = new File(_localPath+_fileName);
var fs:FileStream = new FileStream();
fs.open(file,FileMode.WRITE);
fs.writeBytes(getByteArr(str));
fs.close();
file = null;
fs = null;*/
if(onConnectSucceed!=null) onConnectSucceed(data);
} }
private function onError(e:IOErrorEvent):void
{
trace("error:"+e.text);
} /**
* 访问接口,获取数据
* @param connectPath:接口地址
* @param path : 将接口返回的json写入本地,此为本地地址
*/
public function connect(connectPath:String,fileName:String,localPath:String="",argument:URLVariables=null,callback:Function=null,who:String=""):void
{
_connectionURL = connectPath; _fileName = fileName;
localPath ==""?_localPath = File.applicationDirectory.nativePath+"/json/": _localPath = localPath;
trace("接口地址:"+connectPath);
var request:URLRequest = new URLRequest(connectPath);
request.method = URLRequestMethod.POST;
if(argument){
request.data = argument;
_argument = argument.parameter;
}else{
_argument = "无参数";
}
_ldr.load(request); if(callback!=null) onConnectSucceed = callback;
}
/**
* 将String转换成ByteArray类型
* @param param 被转换的String
* @return ByteArray 转换后的ByteArray
*
*/
private function getByteArr(param:String):ByteArray
{
var bytes:ByteArray = new ByteArray;
bytes.writeUTFBytes(param);
return bytes;
}
}
}

下载文件类 DownloadFile.as

package com.controls.download
{
import com.models.Config; import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.net.URLRequestHeader;
import flash.utils.ByteArray; /**
* 下载文件工具类
* @author Frost.Yen
* @E-mail 871979853@qq.com
* @create 2017-2-16 下午12:55:22
*
*/
public class DownloadFile extends EventDispatcher
{
private var _downloadLoader:URLLoader;
/**
* 是否下载完成标识
*/
private var _downloadEnd:Boolean;
private var _startPoint:uint = 0;
private var _endPoint:uint = 0;
private var _total:uint = 0;
/**
* 文件名(xx.jpg,xx.flv)
*/
private var _fileName:String;
/**
* 下载时保存的临时路径,下载完成后需要从这个地址移动到程序访问的路径
*/
private var _tempPath:String = "";
/**
* 程序访问资源的本地路径
*/
private var _localPath:String = "";
/**
* 服务端抓取数据的路径
*/
private var _remotePath:String = "";
/**
* 下载完成回调函数
*/
private var _downloadComplete:Function; public function DownloadFile()
{
init();
}
private function init():void
{
_downloadLoader = new URLLoader();
_downloadLoader.dataFormat = URLLoaderDataFormat.BINARY;
_downloadLoader.addEventListener(Event.COMPLETE,onLoaded);
_downloadLoader.addEventListener(IOErrorEvent.IO_ERROR,onError);
}
private function onLoaded(e:Event):void
{
if(e.target.data.length == 0){
writeBytes(_tempPath,e.target.data,0,e.target.data.length);
this.dispatchEvent(new Event(Event.COMPLETE));
if(_downloadComplete!=null) _downloadComplete();
}else{
if(_downloadEnd){
_startPoint = _endPoint;
writeBytes(_tempPath,e.target.data,0,e.target.data.length);
this.dispatchEvent(new Event(Event.COMPLETE));
if(_downloadComplete!=null) _downloadComplete();
}else{
_startPoint = _endPoint;
writeBytes(_tempPath,e.target.data,0,e.target.data.length-1);
stepDownload();
}
}
}
/**
* 将数据写入到本地,即下载
* @param path 本地保存地址
* @param bytes 要写入的字节数组。
* @param offset 从零开始的索引,指定在数组中开始写入的位置。
* @paramlength 一个无符号整数,指定在缓冲区中的写入范围。
*/
private function writeBytes(path:String,bytes:ByteArray, offset:uint=0, length:uint=0):void
{
var file:File = new File(path+_fileName);
var fs:FileStream = new FileStream();;
fs.open(file,FileMode.UPDATE);
fs.position = fs.bytesAvailable;//将指针指向文件尾
fs.writeBytes(bytes,offset,length);//在文件中写入新下载的数据
fs.close();
}
/**
* 分步下载
*/
private function stepDownload():void
{
_endPoint += 10000000;
if(_endPoint > _total ){
_endPoint = _total;
_downloadEnd = true;
}
var request:URLRequest = new URLRequest(_remotePath+_fileName);
var header:URLRequestHeader = new URLRequestHeader("Range","bytes="+_startPoint+"-"+_endPoint);
request.requestHeaders.push(header);
_downloadLoader.load(request);
}
/**
* 开始下载文件
* @param remoteURL 数据存放的远程地址
* @param fileName 下载的文件名
* @param tempPath 下载保存到本地的临时目录
* @param localPath 最终程序访问的本地目录
*/
public function download(remotePath:String,fileName:String,tempPath:String,localPath:String,callback:Function=null):void
{
_remotePath = remotePath;
_fileName = fileName;
_tempPath = tempPath;
_localPath = localPath; _downloadComplete = callback;
_downloadEnd = false;
_startPoint = 0;
_endPoint = 0;
var file:File = new File(_localPath+_fileName);
if(file.exists){//假如存在此文件,就不下载,跳过
this.dispatchEvent(new Event(Event.COMPLETE));//可以回调,可以派发
if(_downloadComplete!=null) _downloadComplete();
}else{
_downloadLoader.addEventListener(ProgressEvent.PROGRESS,onProgress);
_downloadLoader.addEventListener(IOErrorEvent.IO_ERROR,onError);
try
{
_downloadLoader.load(new URLRequest(_remotePath+_fileName));
}
catch(error:Error)
{
trace(error.message);
}
}
}
private function onProgress(e:ProgressEvent):void
{
_total = _downloadLoader.bytesTotal;
_downloadLoader.removeEventListener(ProgressEvent.PROGRESS,onProgress);
_downloadLoader.close();
stepDownload();
}
private function onError(e:IOErrorEvent):void
{
trace(e.text);
//错误时跳过,继续下一个下载
if(_downloadComplete!=null) _downloadComplete();
}
/**
* 释放下载工具
*/
public function dispose():void
{
_downloadLoader.removeEventListener(Event.COMPLETE,onLoaded);
_downloadLoader.removeEventListener(IOErrorEvent.IO_ERROR,onError);
_downloadLoader.removeEventListener(ProgressEvent.PROGRESS,onProgress);
_downloadLoader.close();
_downloadLoader = null;
}
} }

文件操作类 FileManager.as

package com.controls.download
{ import flash.events.Event;
import flash.filesystem.File; /**
* 文件操作类
* @author Frost.Yen
* @E-mail 871979853@qq.com
* @create 2017-2-20 上午11:34:16
*
*/
public class FileManager
{
private static var _moveCount:int;
private static var _moveComplete:Function;
private static var _targetDir:String;
private static var _tempDir:String;
private static var _templist:Array; public function FileManager()
{
}
public static function reset():void
{
_moveCount = 0;
_templist = null;
}
/**
* 在目标目录下删除数组中不存在的文件
* @param filesName 文件名数组
* @param targetDir 目标文件夹
*/
public static function deleteFilesByNotSame(filesName:Array,targetDir:String):void
{
var targetList:Array = new File(targetDir).getDirectoryListing();
for(var i:int;i<targetList.length;i++){
if(filesName.indexOf(targetList[i].name)==-1){
(targetList[i] as File).deleteFile();
trace("删除文件:"+(targetList[i] as File).nativePath+"\n");
}
}
}
/**
* 开始移动文件
* @param tempDir 存储下载文件的临时目录
* @param targetDir 需要移动到的目标目录
* @callba 移动完成,回调函数
*/
public static function startMoveFiles(tempDir:String,targetDir:String,callback:Function):void
{
_moveCount = 0;
_targetDir = targetDir;
_tempDir = tempDir;
_moveComplete = callback;
_templist = new File(_tempDir).getDirectoryListing();
if(_templist.length){
moveFiles();
}else{
_moveComplete();
} }
/**
* 移动文件
*/
private static function moveFiles():void
{
var fromFile:File = new File(_tempDir+_templist[_moveCount].name);
var toFile:File = new File(_targetDir+_templist[_moveCount].name);
trace("移动文件:"+_moveCount+"个-->>"+_templist[_moveCount].name);
trace(_tempDir+_templist[_moveCount].name,_targetDir+_templist[_moveCount].name);
fromFile.moveToAsync(toFile,true);
fromFile.addEventListener(Event.COMPLETE,onFileMoveComplete);
} private static function onFileMoveComplete(e:Event):void
{ _moveCount++;
if(_moveCount>_templist.length-1){
//全部移动完成
_moveComplete();
}else{
moveFiles();
} }
}
}

还有个数据存储类 Config.as

package com.models
{
import flash.filesystem.File; /**
*
* @author Frost.Yen
* @E-mail 871979853@qq.com
* @create 2017-2-16 下午1:35:43
*
*/
public class Config
{
public static var config:XML;
/**
* 服务器连接地址
*/
public static var connection:String;
/**
* 远程资源地址 cdn
*/
public static var source:String;
/**
* 本地资源地址
*/
public static var assets:String;
/**
* 存储所有下载资源的信息(目前仅存文件名称)
*/
public static var downloadData:Array = [];
/**
* 写入到本地的json目录地址
*/
public static var jsonPath:String = File.applicationDirectory.nativePath+"/data/";
/**
* 下载资源的临时存放目录
*/
public static var tempPath:String = File.applicationDirectory.nativePath+"/source/";
/**
* 接口返回的json数据组合
*/
public static var jsonArr:Array = [];
public function Config()
{
}
}
}

若要为己所用,据具体需求请改代码。

[ActionScript 3.0] File下载工具的更多相关文章

  1. FTP上传下载工具(FlashFXP) v5.5.0 中文版

    软件名称: FTP上传下载工具(FlashFXP) 软件语言: 简体中文 授权方式: 免费试用 运行环境: Win 32位/64位 软件大小: 7.4MB 图片预览: 软件简介: FlashFXP 是 ...

  2. 今日头条、抖音、西瓜、火山、微视、陌陌等自媒体平台小视频批量下载工具v1.1.0(视频搬运福利)

    前言 目前各大自媒体平台爆火,网络流量暴涨,各大自媒体平台的小视频为广大个广告主带来了如泉涌般的的视频流量,更给广大的自媒体小编带来了丰厚的利益回报,想要创做更多的自媒体内容着实不易,下面给广大的小视 ...

  3. [No00006B]方便的网络下载工具wget 可下载网站目录下的所有文件(可下载整个网站)

    wget是linux下命令行的下载工具,功能很强大,它能完成某些下载软件所不能做的,比如如果你想下载一个网页目录下的所有文件,如何做呢?网络用户有时候会遇到需要下载一批文件的情况,有时甚至需要把整个网 ...

  4. wget下载工具

    转自于:http://www.jb51.net/LINUXjishu/86326.html 1.使用wget下载单个文件  e.g. wget http://cn.wordpress.org/word ...

  5. Windows SharePoint Services 3.0编码开发工具和技巧(Part 1 of 2)

    转:http://blog.csdn.net/mattwin/article/details/2074984 WSSv3 Technical Articles_Windows SharePoint S ...

  6. 【转】学习Flex ActionScript 3.0 强烈推荐电子书

    学习Flex ActionScript 3.0 强烈推荐电子书 AdvancED ActionScript 3.0 Animation(<Make things  move>姐妹篇,强烈推 ...

  7. [Python]豆瓣用户读书短评下载工具

    简介 朋友问我能不能做一个下载他在豆瓣读书上的短评的工具,于是就做了这个“豆瓣用户读书短评下载工具”. GitHub链接:https://github.com/xiaff/dbc-downloader ...

  8. 【转】curl 命令行下载工具使用方法小结

    获取curl curl 命令行下载工具 curl的官方网站为: http://curl.haxx.se官方下载页面为:http://curl.haxx.se/download.html 你可能并不清楚 ...

  9. ftp上传下载工具类

    package com.taotao.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileNo ...

随机推荐

  1. TIME_WAIT和CLOSE_WAIT状态区别

    [TIME_WAIT和CLOSE_WAIT状态区别] 常用的三个状态是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭. TCP协议规定,对 ...

  2. 48. Rotate Image (Array)

    You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...

  3. for 续9

    -------siwuxie095                 for 拾遗:         一: for 语句里,do 后面一般会有括号,有括号就是复合语句, 假如需要用到括号里的变量,就需要 ...

  4. day24,python习题

    今日作业 有两个列表,分别存放来老男孩报名学习linux和python课程的学生名字 linux=['钢弹','小壁虎','小虎比','alex','wupeiqi','yuanhao'] pytho ...

  5. Laravel 5 项目部署到生产环境的实践

    作者:mrcn链接:https://www.zhihu.com/question/35537084/answer/181734431来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...

  6. Executing a Finite-Length Task in the Background

    [Executing a Finite-Length Task in the Background] Apps that are transitioning to the background can ...

  7. shell 用环境变量的值修改properties文件

    假设有如下属性文件 demo.properties user.name=test user.password=123456 ............................... 需求:先需要 ...

  8. 加载 bean.xml 的几种方式 (java or web project)

    1. java project ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:bean1.xm ...

  9. UVA 11997 K Smallest Sums 优先队列 多路合并

    vjudge 上题目链接:UVA 11997 题意很简单,就是从 k 个数组(每个数组均包含 k 个正整数)中各取出一个整数相加(所以可以得到 kk 个结果),输出前 k 小的和. 这时训练指南上的一 ...

  10. linux 输出

    在学习Linux的过程中,常会看到一些终端命令或者程序中有">/dev/null 2>&1 "出现,由于已经遇到了好几次了,为了理解清楚,不妨花点时间百度或者g ...