Flash AIR)AIR操作zip解压文件到指定目录下
延续前些日子的问题,我用AIR开发一个断点续传的工具(好像没贴博客上,稍后放出)。我用这个AIR工具下载了一个zip文件,当我下载完成后,我希望通过AIR控制其自动解压压缩包内的文件到我指定的目录下。
.
这需要用到as3操作zip压缩包数据的方法。
.
我在网络上搜索了一下前人的操作zip相关类包,比如ZIPArchive、fzip、ZIPer(Y.Boy)、Fzlib,发现这些类包虽然定义了比如读取zip内部文件、将文件打包为zip的方法,但是对于读取zip数据后,怎样将这些数据转化为操作系统中的实际文件都没有给出实际方法(或者我没有理解透彻)。
.
其实也不怪这些位大大们,他们都给出了获得文件的ByteArray的方法,那么只要操作这些ByteArray就可以生成相应的实际文件,这都是flash自己的方法。我写这篇教程要讲的就是这后续实际要做的工作,即如何真实的将zip压缩包解压。
.
注意:本文使用了ZIPArchive类包,这个类包应该是位国人所写,此类包下载参考http://code.google.com/p/as3-ziparchive/,当然用其他类包也是可以实现的,只需要用他们的读取zip中BytesArray的方法即可。
.
步骤:http://hi.baidu.com/taotao5453
1、首先,使用Flash CS3或CS4创建一个新的flash AIR工程。工程目录如下,如图1,文件夹“riaidea”就是上面下载的ZIPArchive类包;example_me.fla是新建的AIR工程的主文件,它的文档类填写“Example”;Example.as就是.Fla的文档类;test.zip是一会要操作解压的类,它的内部一共有三个文件,分别是.jpg、.gif、.xml格式,如图2。
(图1):
(图2):
.
2、Example.as类
在这里可以看到,我们之所以创建AIR工程,是为了使用AIR的相关API:File、 FileStream、 FileMode,用来操作系统中的文件,普通的flash CS工程是不能使用的。
package {
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.ProgressEvent;
import flash.utils.ByteArray;
import flash.events.Event;
import flash.events.IOErrorEvent;
import riaidea.utils.zip.ZipArchive;
import riaidea.utils.zip.ZipEvent;
import riaidea.utils.zip.ZipFile;
import flash.filesystem.File;//AIR only
import flash.filesystem.FileMode;// AIR only
import flash.filesystem.FileStream;// AIR only
public class Example extends Sprite {
private var zip1:ZipArchive = new ZipArchive();
public function Example() {
//加载一个zip档案
zip1.load("test.zip");
zip1.addEventListener(ProgressEvent.PROGRESS, loading);
zip1.addEventListener(ZipEvent.ZIP_INIT, inited);
zip1.addEventListener(ZipEvent.ZIP_FAILED, failed);
zip1.addEventListener(IOErrorEvent.IO_ERROR, ioError);
}
private function inited(evt:ZipEvent):void {
zip1.removeEventListener(ProgressEvent.PROGRESS, loading);
zip1.removeEventListener(ZipEvent.ZIP_INIT, inited);
zip1.removeEventListener(ZipEvent.ZIP_FAILED, failed);
/******以下用来操作解压zip*******/
var len:int = zip1.length;
for(var i=0; i<len; i++){
var newZipFile:ZipFile = zip1.getFileAt(i);
var byteArray:ByteArray = new ByteArray();
byteArray = newZipFile.data;
var fileStr:FileStream = new FileStream();
var file:File = new File("d:/temp/" + newZipFile.name);//创建新的File方便后面向File写入数据
fileStr.open(file, FileMode.UPDATE);//以更新形式打开文件,准备更新
fileStr.position = fileStr.bytesAvailable;//将指针指向文件尾
fileStr.writeBytes(byteArray, 0, byteArray.length);//在文件中写入新下载的数据
fileStr.close();//关闭文件流
}
}
private function loading(evt:ProgressEvent):void {
//trace(evt.currentTarget, evt.bytesLoaded, evt.bytesTotal);
}
private function failed(evt:ZipEvent):void {
//trace(evt.content);
}
private function ioError(evt:IOErrorEvent):void {
//trace(evt);
}
}
}
.
3、对example_me.fla使用Crtl+Enter调试,我们就可以在d:/temp/下找到解压出来的三个文件了,即成功!
.
4、说明:ZIPArchive类包中还有ZIPArchive的addFileFromString、getBitmapByName、removeFileByName方法可以操作压缩包内的文件。我正在试验如何解压内部带文件夹的zip,我想上面的Example.as可能需要完善一下,文章先发到这里了!!http://hi.baidu.com/taotao5453
********************
********************
经测试,以下方法对有文件夹的zip压缩包也有效,一个文件如果是在压缩包的一个文件夹里,那么当取它的newZipFile.name名字时是带路径的名字,例如sample123/logo.gif,在使用 fileStr.open(file, FileMode.WRITE); 时会自动先创建文件上一级的文件夹,然后在生成文件logo.gif。
(使用以下方法替换inited方法中的for循环即可):
for(var i=0; i<len; i++){
var newZipFile:ZipFile = zip1.getFileAt(i);
var byteArray:ByteArray = new ByteArray();
byteArray = newZipFile.data;
var fileStr:FileStream = new FileStream();
var file:File = new File;//C:\Documents and Settings\username
file = file.resolvePath("D:/temp/" + newZipFile.name);
trace(newZipFile.name);
if(file.isDirectory == false){ //判断是否为文件夹,不是文件夹时候向下进行,按照文件的目录结构依次生成文件夹、文件
fileStr.open(file, FileMode.WRITE); //以写形式打开文件,准备更新
fileStr.writeBytes(byteArray, 0, byteArray.length); //在文件中写入新下载的数据
fileStr.close();//关闭文件流
}else{
}
}