AS3でZipファイルを解凍

by zahir
♥25 | Line 116 | Modified 2009-12-15 19:45:20 | MIT License
play

ActionScript3 source code

/**
 * Copyright zahir ( http://wonderfl.net/user/zahir )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/58K8
 */

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
	applicationComplete="init();"
	width="465" height="465">
	<mx:Script>
		<![CDATA[
			//
			/*
				zipファイルの解凍をしてみました。
				
				今度は圧縮をしてみたいけどフォルダの扱いがよく分からない…
				誰か教えてくだしあ
			 */
			private const IMG:Array = ["jpg","jpeg", "gif", "png"];
			
			private var fileType:String;
			private var fr:FileReference;
			
			private function init():void{
				t.text = "Zipファイルを解析してみる。\n\n" + 
						"load Zip ボタンをクリックして、zipファイルをロードしてください。";
			}
			private function load():void{
				fr = new FileReference();
				fr.addEventListener(Event.SELECT, onSelect );
				fr.browse( [ new FileFilter("load zip file (*.zip)", "*.zip;")] );
			}
			private function onSelect(e:Event):void{
				fr.removeEventListener(Event.SELECT, onSelect);
				fr.addEventListener(ProgressEvent.PROGRESS, onProg);
				fr.addEventListener(Event.COMPLETE, onComp);
				t.text = "";
				fr.load();
			}
			private function onProg( e:ProgressEvent ):void{
				t.text = "" + ((e.bytesLoaded / e.bytesTotal ) * 100) + " %";
			}
			private function onComp(e:Event):void{
				fr.removeEventListener(ProgressEvent.PROGRESS, onProg);
				fr.removeEventListener(Event.COMPLETE, onComp );
				t.text = fr.name + " Loading Complete !!\n\n";
				analysis( fr.data as ByteArray );
			}
			private function analysis( data:ByteArray ):void{
				var lite:String = Endian.LITTLE_ENDIAN;
				var signature:uint;
				var compression:int;
				var offset:uint;
				var fileNameLength:uint;
				var fieldLength:uint;
				var fileName:String = "";
				var compSize:uint;
				var uncompSize:uint;
				var n:int = 0;
				
				// 読み取りが不可能になるまでループ
				while(data.bytesAvailable){
					var b:ByteArray = new ByteArray();
					b.endian = lite;
					
					data.readBytes( b, 0, 30); //ヘッダの長さは30
					
					//0x04034b50 以外は読み取るファイルがないのでループを脱出
					signature = b.readInt();
					if( signature != 0x04034b50) break;
					
					b.position = 8;
					
					// 圧縮方法を調べる
					compression = b.readByte(); // 8 = DEFLATE , 0 = UNCOMPRESSED
					
					// ヘッダ直後の可変長部分の長さを調べる
					offset = 0;
					b.position = 26;
					fileNameLength = b.readShort();
					fieldLength = b.readShort();
					offset = fileNameLength + fieldLength;
					
					data.readBytes( b, 30, offset );
					
					// ファイル名・ファイルの圧縮サイズ・非圧縮サイズを調べる
					b.position = 18;
					compSize = b.readUnsignedInt();
					b.position = 22;
					uncompSize = b.readUnsignedInt();;
					b.position = 30;
					fileName = b.readUTFBytes( fileNameLength );
					
					t.text += "fileName  ::  " + fileName + "\n" + 
							"\t" + "compress  ::  " + compression + "\n" + 
							"\t" + "compressed size  ::  " + compSize + "\n" + 
							"\t" + "uncompressed size  ::  " + uncompSize + "\n";
					
					if(compSize >=1 ){
						data.readBytes( b, 0, compSize);
						
						// 8だったらinfalteで解凍
						if(compression == 8) b.inflate();
						
						b.position = 0;
						if(new RegExp(".txt","i").test( fileName) ){
							t.text += "\t" + "type  ::  Text File\n";
							t.text += "\t" + "text  ::  \n" + 
									"\t******************************************\n" + 
									"\t\t" + b.readUTFBytes( uncompSize ) + "\n" + 
									"\t******************************************\n";
						}else if(checkImgs( fileName)){
							t.text += "\t" + "type  ::  " + fileType + "\n";
							var l:Loader = new Loader();
							l.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void{
								l.width = 50;
								l.scaleY = l.scaleX;
								l.filters = [ new GlowFilter( 0x0, 1, 5,5)];
							});
							l.loadBytes(b);
							c.addChild( l );
						}else{
							t.text += "\t" + "type  ::  other\n";
						}
					}else{
						t.text += "\t" + "type  ::  Folder\n";
					}
					t.text += "\n";
				}
			}
			private function checkImgs( fileName:String ):Boolean{
				var len:int = IMG.length;
				for(var i:int = 0; i<len; i++){
					var extension:String = IMG[i];
					var target:String = fileName.substr(fileName.length - extension.length, fileName.length);
					if(new RegExp(extension, "i").test( target ) ){
						fileType = extension;
						return true;
					}
				}
				return false;
			}
		]]>
	</mx:Script>
	<mx:TextArea id="t" left="10" right="70" top="10" bottom="40" editable="false"/>
	<mx:UIComponent id="c" right="60" top="10" />
	<mx:Button x="10" label="load Zip" bottom="10" height="22" click="load()"/>
</mx:Application>