feb19.jp

Nobuhiro Takahashi
Designer / Engineer

AIR で JSON 形式ファイルの入出力

AIR で JSON 形式ファイルの入出力

AIR 祭り開催中。今回はファイル入出力。AS3 で扱っている Object 型のデータを JSON ファイルとして保存してみるメモ。

Flash CS4 または CS3 + AIR 開発キットで、パブリッシュ設定 AIR 1.5 の .fla ファイルを作成して、SWF 作るようにドキュメントクラスに FileSaveAndReadTest と設定。

ステージ上に save_btn / load_btn / dummy_btn を配置して実行してください。

FileStream.open() ではなく FileStream.openAsync() を使って非同期に書き込みます。
(イベントリスナーで終了を受け取ったりする必要があるけど、プログレスバーとかも出せたり、大きなファイルを扱うときも open() した瞬間プログラムを停止させない)

ちなみに JSON を使うので、Adobe の as3corelib を入手する必要があります。

FileSaveAndReadTest.as
 
package 
{
	import com.adobe.serialization.json.JSON;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.ProgressEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	
	public class FileSaveAndReadTest extends Sprite
	{
		private var _data:Object;
		
		public function FileSaveAndReadTest()
		{
			// ステージにボタンがわりにする適当な MovieClip を設置
			save_btn.addEventListener(MouseEvent.CLICK, clickHandler);
			load_btn.addEventListener(MouseEvent.CLICK, clickHandler);
			dummy_btn.addEventListener(MouseEvent.CLICK, clickHandler);
		}
		
		private function clickHandler(event:MouseEvent):void
		{
			// クリックされたとき
			var target:MovieClip = MovieClip(event.currentTarget);
			switch(target.name)
			{
				case "save_btn":
					if (!_data)	return;
					// ダミーデータに変更(加算)を加えて保存
					_data.test[1] += 10;
					save();
					break;
				
				case "load_btn":
					// データを読み込む
					load();
					break;
				
				case "dummy_btn":
					// ダミーデータを突っ込む
					_data = {
						"test":	[0, 1, 2, 3, 4, 5],
						"testtest": "testtest",
						"testtesttest": {
							"test": [5, 4, 3, 2, 1, 0],
							"testtest": "unko"
						}
					}
					break;
			}
		}
		
		public function save():void
		{
			// AIR アプリ固有のデータ保存スペース
			trace(File.applicationStorageDirectory.url);
			var file:File = File.applicationStorageDirectory.resolvePath("sample.json");
			
			// ユーザーのデスクトップにする場合は File.desktopDirectory.resolvePath("sample.json");
			// ユーザーのドキュメントディレクトリにする場合は File.documentsDirectory.resolvePath("sample.json");
			// ユーザーのホームディレクトリにする場合は File.userDirectory.resolvePath("sample.json");
			// アプリケーションのリソースがインストールされているディレクトリにする場合は File.applicationResourceDirectory.resolvePath("sample.json");
			
			// オブジェクトを JSON ファイル形式に変換
			var json:String = JSON.encode(_data);
			
			// FileStream 使う
			var fs:FileStream = new FileStream();
			fs.openAsync(file, FileMode.WRITE);	// 書き込みモードで非同期的に開く
			fs.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			fs.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			//fs.addEventListener(Event.CLOSE, closeHandler);
			fs.addEventListener(Event.COMPLETE, saveCompleteHandler);
			
			// 書き込む
			fs.writeUTFBytes(json);
		}
		
		private function ioErrorHandler(event:IOErrorEvent):void
		{
			trace(event.text);
		}
		
		private function progressHandler(event:ProgressEvent):void
		{
			
		}
		
		private function closeHandler(event:Event):void
		{
			
		}
		
		private function saveCompleteHandler(event:Event):void
		{
			// 閉じる
			var fs:FileStream = FileStream(event.currentTarget);
			fs.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			fs.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
			//fs.removeEventListener(Event.CLOSE, closeHandler);
			fs.removeEventListener(Event.COMPLETE, loadCompleteHandler);
			fs.close();
		}
		
		public function load():void
		{
			// AIR アプリ固有のデータ保存スペース
			trace(File.applicationStorageDirectory.url);
			var file:File = File.applicationStorageDirectory.resolvePath("sample.json");
			
			var fs:FileStream = new FileStream();
			fs.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			fs.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			//fs.addEventListener(Event.CLOSE, closeHandler);
			fs.addEventListener(Event.COMPLETE, loadCompleteHandler);
			fs.openAsync(file, FileMode.READ);
		}
		
		private function loadCompleteHandler(event:Event):void
		{
			var fs:FileStream = FileStream(event.currentTarget);
			fs.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			fs.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
			//fs.removeEventListener(Event.CLOSE, closeHandler);
			fs.removeEventListener(Event.COMPLETE, loadCompleteHandler);
			
			// ファイルを文字列に変換して JSON デコード
			var str:String = fs.readUTFBytes(fs.bytesAvailable);
			var obj:Object = JSON.decode(str);
			
			// 一応中身の一部トレース
			trace(obj.test[1]);
			
			_data = obj;
			
			// 閉じる
			fs.close();
		}
	}
	
}

SharedObject とあんまり変わらん気もしますけど、保存容量制限問題とか、ファイルが任意の場所に作れるとか、多少自由が効きますね。

Tweet Share Bookmark

Navigation

prev: Adobe CS5 ティザーサイトオープン
next: Mac OS X 10.6 Snow Leopard から入ってるフォント「Menlo」がコーディング作業にいい感じ

Recently Entries