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

