Last active
December 29, 2015 00:28
-
-
Save alumican/7585773 to your computer and use it in GitHub Desktop.
zipファイルをダウンロードしてメモリ上に非同期展開するクラス
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* zipファイルをダウンロードしてメモリ上に非同期展開する | |
* | |
* var loader:ZipLoader = new ZipLoader(); | |
* loader.addEventListener(ZipLoaderEvent.COMPLETE, completeHandler); | |
* loader.addEventListener(ZipLoaderEvent.ERROR, errorHandler); | |
* loader.addEventListener(ZipLoaderEvent.EXECUTED, executedHandler); | |
* loader.load("http://path_to.zip"); | |
* | |
* function completeHandler(event:ZipLoaderEvent):void { | |
* trace("成功"); | |
* | |
* //ダウンロードしたzip内のファイルパス一覧 | |
* trace(loader.paths); | |
* | |
* //中身を取得する | |
* var textBytes:ByteArray = loader.getData("path/to/text.txt"); | |
* var text:String = textBytes.readUTFBytes(textBytes.length); | |
* | |
* var imageBytes:ByteArray = loader.getData("path/to/image.png"); | |
* var image:Loader = new Loader(); | |
* image.loadBytes(imageBytes); | |
* | |
* var soundBytes:ByteArray = loader.getData("path/to/sound.mp3"); | |
* var sound = new Sound(); | |
* sound.loadCompressedDataFromByteArray(soundBytes, soundBytes.length); | |
* | |
* //メモリの破棄(上記のByteArrayも削除されるので参照を保持している場合は注意) | |
* //loader.dispose(); | |
* } | |
* | |
* function errorHandler(event:ZipLoaderEvent):void { | |
* trace("失敗"); | |
* } | |
* | |
* function executedHandler(event:ZipLoaderEvent):void { | |
* trace("成功でも失敗でも最後に呼ばれる"); | |
* } | |
*/ | |
package ziploader | |
{ | |
import com.coltware.airxzip.ZipEntry; | |
import com.coltware.airxzip.ZipEvent; | |
import com.coltware.airxzip.ZipFileReader; | |
import flash.events.ErrorEvent; | |
import flash.events.Event; | |
import flash.events.IOErrorEvent; | |
import flash.events.SecurityErrorEvent; | |
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.utils.ByteArray; | |
import flash.utils.getTimer; | |
import starling.events.EventDispatcher; | |
/** | |
* zipファイルをダウンロードしてメモリ上に展開する | |
*/ | |
public class ZipLoader extends EventDispatcher | |
{ | |
//---------------------------------------------------------- | |
// | |
// Constructor | |
// | |
//---------------------------------------------------------- | |
public function ZipLoader():void | |
{ | |
_datasByPath = new Object(); | |
_paths = new Vector.<String>(); | |
_isLoaded = _isLoading = false; | |
} | |
//---------------------------------------------------------- | |
// | |
// Property | |
// | |
//---------------------------------------------------------- | |
//-------------------------------------- | |
// isLoaded | |
//-------------------------------------- | |
private var _isLoaded:Boolean; | |
public function get isLoaded():Boolean | |
{ | |
return _isLoaded; | |
} | |
//-------------------------------------- | |
// isLoading | |
//-------------------------------------- | |
private var _isLoading:Boolean; | |
public function get isLoading():Boolean | |
{ | |
return _isLoading; | |
} | |
//-------------------------------------- | |
// paths | |
//-------------------------------------- | |
private var _paths:Vector.<String>; | |
/** | |
* zip内のファイルパス配列 | |
*/ | |
public function get paths():Vector.<String> | |
{ | |
return _paths; | |
} | |
/** | |
* @private | |
*/ | |
private var _datasByPath:Object; | |
private var _file:File; | |
private var _fileStream:FileStream; | |
private var _loader:URLLoader; | |
private var _queue:Vector.<ZipEntry>; | |
private var _reader:ZipFileReader; | |
//---------------------------------------------------------- | |
// | |
// Function | |
// | |
//---------------------------------------------------------- | |
/** | |
* インスタンスを破棄する | |
*/ | |
public function dispose():void | |
{ | |
if (_loader) | |
{ | |
try | |
{ | |
_loader.removeEventListener(flash.events.Event.COMPLETE, _loaderCompleteHandler); | |
_loader.removeEventListener(IOErrorEvent.IO_ERROR, _loaderErrorHandler); | |
_loader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, _loaderErrorHandler); | |
_loader.data = null; | |
_loader.close(); | |
} | |
catch (error:Error) | |
{ | |
} | |
_loader = null; | |
} | |
if (_file) | |
{ | |
try | |
{ | |
_file.deleteFile(); | |
} | |
catch (error:Error) | |
{ | |
} | |
_file = null; | |
} | |
if (_fileStream) | |
{ | |
try | |
{ | |
_fileStream.removeEventListener(flash.events.Event.CLOSE, _fileStreamCloseHandler); | |
_fileStream.removeEventListener(IOErrorEvent.IO_ERROR, _fileStreamErrorHandler); | |
_fileStream.close(); | |
} | |
catch (error:Error) | |
{ | |
_fileStream = null; | |
} | |
} | |
if (_reader) | |
{ | |
try | |
{ | |
_reader.removeEventListener(ZipEvent.ZIP_DATA_UNCOMPRESS, _readerZipDataUncompressHandler); | |
_reader.close(); | |
} | |
catch (error:Error) | |
{ | |
} | |
_reader = null; | |
} | |
if (_datasByPath) | |
{ | |
for each (var data:ByteArray in _datasByPath) | |
data.clear(); | |
_datasByPath = null; | |
} | |
_paths = null; | |
_queue = null; | |
_isLoaded = false; | |
_isLoading = false; | |
} | |
/** | |
* 解凍されたファイルを取得する | |
*/ | |
public function getData(path:String):ByteArray | |
{ | |
return _datasByPath[path]; | |
} | |
/** | |
* zipファイルを読み込む | |
*/ | |
public function load(url:String):void | |
{ | |
//trace("[ZipLoader] Load, url = " + url); | |
dispose(); | |
_datasByPath = new Object(); | |
_paths = new Vector.<String>(); | |
_isLoaded = false; | |
_isLoading = true; | |
//zipファイルをURLから読み込む | |
_loader = new URLLoader(); | |
_loader.addEventListener(flash.events.Event.COMPLETE, _loaderCompleteHandler); | |
_loader.addEventListener(IOErrorEvent.IO_ERROR, _loaderErrorHandler); | |
_loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, _loaderErrorHandler); | |
_loader.dataFormat = URLLoaderDataFormat.BINARY; | |
_loader.load(new URLRequest(url)); | |
} | |
/** | |
* zipファイルの読み込み完了ハンドラ | |
*/ | |
private function _loaderCompleteHandler(event:flash.events.Event):void | |
{ | |
//zipバイナリを一時ファイルとして保存 | |
_file = File.applicationStorageDirectory.resolvePath("tmp_" + getTimer() + ".zip"); | |
_fileStream = new FileStream(); | |
_fileStream.addEventListener(flash.events.Event.CLOSE, _fileStreamCloseHandler); | |
_fileStream.addEventListener(IOErrorEvent.IO_ERROR, _fileStreamErrorHandler); | |
_fileStream.openAsync(_file, FileMode.WRITE); | |
_fileStream.writeBytes(_loader.data); | |
_fileStream.close(); | |
} | |
/** | |
* zipファイルの読み込みエラーハンドラ | |
*/ | |
private function _loaderErrorHandler(event:ErrorEvent):void | |
{ | |
_error("URLLoader, " + event); | |
} | |
/** | |
* 一時ファイルの書き込み完了ハンドラ | |
*/ | |
private function _fileStreamCloseHandler(event:flash.events.Event):void | |
{ | |
_loader.data = null; | |
//zipファイルマネージャを作成 | |
_reader = new ZipFileReader(); | |
//zipファイルかどうかチェック | |
if (!_reader.check(_file)) | |
{ | |
_error("FileStream, file is not zip"); | |
return; | |
} | |
//zipに含まれるファイルリストを抽出 | |
_reader.open(_file); | |
_queue = Vector.<ZipEntry>(_reader.getEntries()); | |
//解凍を開始 | |
_datasByPath = new Object(); | |
_reader.addEventListener(ZipEvent.ZIP_DATA_UNCOMPRESS, _readerZipDataUncompressHandler); | |
_reader.unzipAsync(_queue.pop()); | |
} | |
/** | |
* 一時ファイルの書き込みエラーハンドラ | |
*/ | |
private function _fileStreamErrorHandler(event:ErrorEvent):void | |
{ | |
_error("FileStream, " + event); | |
} | |
/** | |
* zipファイルの解凍ハンドラ | |
*/ | |
private function _readerZipDataUncompressHandler(event:ZipEvent):void | |
{ | |
//解凍したファイルをメモリに保持 | |
var path:String = event.entry.getFilename(); | |
_datasByPath[path] = event.data; | |
_paths.push(path); | |
//trace("[ZipLoader] Uncompressed : " + path); | |
if (_queue.length > 0) | |
{ | |
//次のデータを読み込む | |
_reader.unzipAsync(_queue.pop()); | |
} | |
else | |
{ | |
//全てのファイルを解凍完了 | |
_file.deleteFileAsync(); | |
_reader.removeEventListener(ZipEvent.ZIP_DATA_UNCOMPRESS, _readerZipDataUncompressHandler); | |
_isLoaded = true; | |
_isLoading = false; | |
//trace("[ZipLoader] Complete"); | |
dispatchEvent(new ZipLoaderEvent(ZipLoaderEvent.COMPLETE)); | |
dispatchEvent(new ZipLoaderEvent(ZipLoaderEvent.EXECUTED)); | |
} | |
} | |
/** | |
* エラー処理 | |
*/ | |
private function _error(errorMessage:String):void | |
{ | |
dispose(); | |
_datasByPath = new Object(); | |
_isLoaded = false; | |
_isLoading = false; | |
trace("[ZipLoader] Error : " + errorMessage); | |
dispatchEvent(new ZipLoaderEvent(ZipLoaderEvent.ERROR)); | |
dispatchEvent(new ZipLoaderEvent(ZipLoaderEvent.EXECUTED)); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ziploader | |
{ | |
import starling.events.Event; | |
/** | |
* ZipLoaderによって発行されるイベント | |
*/ | |
public class ZipLoaderEvent extends Event | |
{ | |
//---------------------------------------------------------- | |
// | |
// Static Property | |
// | |
//---------------------------------------------------------- | |
/** | |
* 解凍に完了したときに発行される | |
*/ | |
public static const COMPLETE:String = "ZipLoaderEvent.COMPLETE"; | |
/** | |
* 解凍に失敗したときに発行される | |
*/ | |
public static const ERROR:String = "ZipLoaderEvent.ERROR"; | |
/** | |
* 成否にかかわらず解凍が終了したときに発行される | |
*/ | |
public static const EXECUTED:String = "ZipLoaderEvent.EXECUTED"; | |
//---------------------------------------------------------- | |
// | |
// Constructor | |
// | |
//---------------------------------------------------------- | |
public function ZipLoaderEvent(type:String, bubbles:Boolean = false, data:Object = null):void | |
{ | |
super(type, bubbles, data); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment