• [ActionScript 3.0] File下载工具


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

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

    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+"--
    ");
                    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+"个-----
    ");
                            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+"个资源下载完成
    ");
                    _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("------>>所有资源移动完成--------
    ");
                
                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("
    <<----------------- aticon: "+_connectionURL+" ----------------- argument: "+_argument+" -------------------------->>
    result: 
    "+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+"
    ");
                    }    
                }
            }
            /**
             * 开始移动文件
             * @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()
            {
            }
        }
    }

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

  • 相关阅读:
    Typescript 学习笔记一:介绍、安装、编译
    css 如何“画”一个抽奖转盘
    isBalanced函数实现
    链表(单向链表,双向链表)
    IDEA 插件的安装和使用
    leetCode算法------>>>>数组
    二维数组
    IDEA (2019.3) 字体编码和基本设置
    线性结构和非线性结构
    Java反射
  • 原文地址:https://www.cnblogs.com/frost-yen/p/6433037.html
Copyright © 2020-2023  润新知