flex分析zip文件

 <?xml version="1.0" encoding="utf-8"?>
<mx:Window xmlns:mx="http://www.adobe.com/2006/mxml" title="分析ZIP文件" layout="vertical" width="500" height="300"  
creationComplete="init();">
<mx:Script>
<![CDATA[
import flash.filesystem.*;
import flash.utils.ByteArray;
import flash.events.Event;
private var bytes:ByteArray = new ByteArray();

//定义用来存储文件标头中元数据的变量 variables for reading fixed portion of file header
private var fileName:String = new String();
private var flNameLength:uint;
private var xfldLength:uint;
private var offset:uint;
private var compSize:uint;
private var uncompSize:uint;
private var compMethod:int;
private var signature:int;
private var k:int;
//定义用来表示 .zip 文件的 File (zfile) 和 FileStream (zStream) 对象,并指定将从中提取文件的 .zip 文件的位置(桌面目录
//下名为“HelloAIR.zip” 的文件)。
// File variables for accessing .zip file
private var zfile:File = File.desktopDirectory.resolvePath("HelloAIR.zip");
private var zStream:FileStream = new FileStream();
private function init():void
{
    var screenBounds:Rectangle = Screen.mainScreen.bounds;    
        nativeWindow.x = (screenBounds.width - nativeWindow.width) / 2;
        nativeWindow.y = (screenBounds.height - nativeWindow.height) / 2;    
}
private function readout():void
{
    zStream.open(zfile, FileMode.READ);
    bytes.endian = Endian.LITTLE_ENDIAN;
    while (zStream.position < zfile.size)
    {
            //前 30 个字节组成了第一个文件标头的固定大小部分。
        // read fixed metadata portion of local file header
        zStream.readBytes(bytes, 0, 30);
        bytes.position = 0;        
        signature = bytes.readInt();        
        // 再没有可提取的文件, quit
        if (signature != 0x04034b50)//文件开始标记
        {                
            break;
        }
        
        bytes.position = 8;
        compMethod = bytes.readByte(); // store compression method (8 == Deflate)压缩算法 通常是8,没压缩的是0
        offset = 0;// stores length of variable portion of metadata
        bytes.position = 26; // offset to file name length
        flNameLength = bytes.readShort();// store file name
        trace("flNameLength="+flNameLength);
        offset += flNameLength; // add length of file name
        bytes.position = 28;// offset to extra field length
        xfldLength = bytes.readShort();
        trace("xfldLength="+xfldLength);
        offset += xfldLength;// add length of extra field
        // 接下来程序将读取文件标头的可变长度部分,以将该部分的字节数存储在 offset 变量中。
        zStream.readBytes(bytes, 30, offset);
        
        bytes.position = 30;
        fileName = bytes.readMultiByte(flNameLength,"gbk"); // read file name
        
        taFiles.text += fileName + "/n"; // write file name to text area
        bytes.position = 18;
        compSize = bytes.readUnsignedInt(); // store size of compressed portion
        taFiles.text += "/tCompressed size is: " + compSize + '/n';
        bytes.position = 22; // offset to uncompressed size
        uncompSize = bytes.readUnsignedInt(); // store uncompressed size
        taFiles.text += "/tUncompressed size is: " + uncompSize + '/n';
        //将文件的其余部分按照压缩后大小所指定的长度读入 ,未压缩的长度会等于压缩的,所以长度是对的
        zStream.readBytes(bytes, 0, compSize);
        if (compMethod == 8) // if file is compressed, uncompress
        {
            bytes.uncompress(CompressionAlgorithm.DEFLATE);
        }
        outFile(fileName, bytes);        
    } // end of while loop
    var flen:int=0;
    var externlen:int=0;
    var showlen:int=0;
    while (zStream.position < zfile.size)//目录开始标记为0x02014b50
    {
        if(signature != 0x02014b50)
        break;
        bytes.position = 10;
        compMethod = bytes.readByte();        
        bytes.position = 28;
        flen= bytes.readByte();
        trace("bytes.path len:"+flen);
        zStream.readBytes(bytes, 0, 46-30);
        bytes.position = 0;
        externlen=bytes.readByte();
        trace("bytes.externlen len:"+externlen);
        bytes.position = 2;
        showlen=bytes.readByte();
        trace("bytes.showlen len:"+showlen);
        zStream.readBytes(bytes, 0, flen+externlen+showlen);
        if((zStream.position+30)<zfile.size){
        zStream.readBytes(bytes, 0, 30);
        bytes.position = 0;        
        signature = bytes.readInt();
        }else{                        
        break;
        }
    }
    zStream.readBytes(bytes, 0, 22);
    bytes.position = 0;        
    signature = bytes.readInt();
    if(signature == 0x06054b50){//目录结束标志
        bytes.position = 20;
        showlen=bytes.readByte();
        trace("bytes.show len="+showlen);
        zStream.readBytes(bytes, 22, showlen);
        bytes.position = 22;        
        fileName=bytes.readMultiByte(showlen,"gbk");                
        taFiles.text+="/n注释:"+fileName;
    }    
} // end of init() method

private function outFile(fileName:String, data:ByteArray):void
{
    var outFile:File = File.desktopDirectory; // dest folder is desktop
    outFile = outFile.resolvePath(fileName); // name of file to write
    var outStream:FileStream = new FileStream();
    // open output file stream in WRITE mode
    outStream.open(outFile, FileMode.WRITE);
    // write out the file
    outStream.writeBytes(data, 0, data.length);
    // close it
    outStream.close();
}

private function selectTextFile(root:File):void
    {
        taFiles.text="";
        var txtFilter:FileFilter = new FileFilter("Zip", "*.Zip;*.zip");
        root.browseForOpen("Open", [txtFilter]);
        root.addEventListener(Event.SELECT, fileSelected);
    }
    private function fileSelected(event:Event):void
    {
        msg.text="读文件:"+event.target.nativePath;
    }
// The application code goes here
]]>
</mx:Script>
<mx:Label id="msg" text="只是测试了不包含子目录的几个文件压缩的zip"/><mx:Button label="文件" click="selectTextFile(zfile)" />
<mx:TextArea id="taFiles" width="320" height="150"/>
<mx:Button label="分析" click="readout()" />

</mx:Window>
6 一个 ZIP 文件的普通格式由三个部分组成: 压缩源文件数据区+压缩源文件目录区+压缩源文件目录结束标志
    1、压缩源文件数据区
    在这个数据区中每一个压缩的源文件/目录都是一条记录,记录的格式如下:      
       [文件头+ 文件数据 + 数据描述符]
       a、文件头结构
         组成                     长度
      文件头标记                  4 bytes  (0x04034b50)
      解压文件所需 pkware 版本    2 bytes
      全局方式位标记              2 bytes
    压缩方式                    2 bytes
    最后修改文件时间             2 bytes
    最后修改文件日期             2 bytes
    CRC-32校验                  4 bytes
    压缩后尺寸                  4 bytes
    未压缩尺寸                  4 bytes
    文件名长度                  2 bytes
      扩展记录长度                2 bytes
    文件名                     (不定长度)
    扩展字段                   (不定长度)    
        b、文件数据      
        c、数据描述符
    组成     长度
    CRC-32校验                  4 bytes
    压缩后尺寸                   4 bytes
    未压缩尺寸                   4 bytes
      这个数据描述符只在全局方式位标记的第3位设为1时才存在(见后详解),紧接在压缩数据的最后一个字节后。这个数据描述符只用在不能对输出的 ZIP 文件进行检索时使用。例如:在一个不能检索的驱动器(如:磁带机上)上的 ZIP 文件中。如果是磁盘上的ZIP文件一般没有这个数据描述符。 
     2、压缩源文件目录区
     在这个数据区中每一条纪录对应在压缩源文件数据区中的一条数据
      组成                            长度
      目录中文件文件头标记             4 bytes  (0x02014b50)
      压缩使用的 pkware 版本          2 bytes
      解压文件所需 pkware 版本         2 bytes
      全局方式位标记                   2 bytes
      压缩方式                        2 bytes            10   
      最后修改文件时间                 2 bytes    12
      最后修改文件日期                 2 bytes    14
      CRC-32校验                 4 bytes    18
      压缩后尺寸                      4 bytes        22
      未压缩尺寸                      4 bytes        26
      文件名长度                      2 bytes        28
      扩展字段长度                    2 bytes        30
      文件注释长度                    2 bytes        32
      磁盘开始号                      2 bytes        34
      内部文件属性                    2 bytes        36
      外部文件属性                    4 bytes        38
        局部头部偏移量                  4 bytes        42
      文件名                       (不定长度)    46
      扩展字段                     (不定长度)
        文件注释                     (不定长度)
    3、压缩源文件目录结束标志
       组成                          长度
        目录结束标记                    4 bytes  (0x06054b50)
        当前磁盘编号                    2 bytes        4
        目录区开始磁盘编号              2 bytes        6
      本磁盘上纪录总数                 2 bytes    8
      目录区中纪录总数                 2 bytes    10
      目录区尺寸大小                   4 bytes    12
      目录区对第一张磁盘的偏移量        4 bytes    16
      ZIP 文件注释长度                 2 bytes    20
      ZIP 文件注释                   (不定长度)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值