AIRにおけるファイル操作概要

AIRは、セキュリティのサンドボックス内で動作するFlashと異なり、ファイルシステムに対して無制限にアクセスできる(もちろん、OSが規定するアクセス権の範囲内で)。また、ファイル選択ダイアログなどのコンポーネントが充実しているのも特徴だ。簡単なプログラミングで、ファイルを扱うUIを作成できるのは勿論のこと、OSがネイティブで用意しているファイル選択ダイアログも取り扱える。

こうしたAIRのファイルシステムAPIは、二つの基本的なクラスの上に立脚している。一つは、ファイルやディレクトリの抽象化表現であるflash.filesystem.Fileクラスだ。もう一つは、ファイル内のデータを読み書きするためのストリームを操作するflash.filesystem.FileStreamクラスである。

今回から3回にわたり、これらのクラスをベースとするファイルシステムAPIについて解説する。今回はまず、Fileクラスを用いたファイル操作を解説し、次回、ファイルを取り扱うための各種コンポーネントを紹介する。また、ファイル操作編の最後では、FileStreamを用いたファイルの読み書きを解説する予定だ。

flash.filesystem.Fileクラスの生成

先ほども述べたとおり、flash.filesystem.Fileクラスはファイルやディレクトリの抽象的な表現だ。ファイルもディレクトリも統一的に扱うという点が一つの特徴だ。Fileクラスによって表されるファイル/ディレクトリのメソッドを用いて、それらをコピー/移動/削除することが簡単に行える。もう一つの特徴としては、flash.filesystem.Fileクラスは、存在しないファイルやディレクトリを表すこともできる。こうした特徴から、Javaにおけるjava.io.Fileクラスが持つ位置づけと非常に近いものがある。

ではまず、Fileクラスのインスタンスを作成するところから始めよう。

Fileクラスのコンストラクタは、文字列で表されるファイルパスを一つ引数にとることができる(必須ではない)。以下のような形だ。

// C:\Documents and Settingsを表すFileオブジェクトを作成
var file:File = new File("C:\\Documents and Settings\\");

上記のコンストラクタで使用したパスは、ネイティブパスと呼ばれ、プラットフォームごとに異なる表現をとるパス文字列だ。Windows環境であればパスの区切り文字は「\」もしくは「/」を利用することができ、Mac OS Xでは区切り文字は「/」となる。FileクラスのnativePathプロパティを介して参照したり、セットしたりすることができる。

また、プラットフォームに依存しない、ファイルパスの表現としてURLを使用することが可能だ。URLは、Fileクラスのurlプロパティで表され、参照することも、後からセットすることも可能だ。

var file:File = new File();

file.url = "file:///c:"; // Cドライブを表すURL
file.url = "file:///c:/temp/"; // C:\tempを表すURL
file.url = "file:///c:/temp/temp.txt"; // ファイルを表すURL

URLの書式に注意してほしい。

fileクラスは、ローカルディスクを表すプロトコル文字列である。また、AIRならではのURLスキーマとして、以下のようなものが使用可能だ。

  • app-resource - AIRアプリケーション固有のリソースを保持しておくためのディレクトリ。アプリケーションディスクリプタが存在しているディレクトリを指す
  • app-strage - AIRアプリケーションが扱うデータを保持しておくためのディレクトリで、データベースファイルなどを格納するとよい

これらのディレクトリは、プラットフォームごとに固有の場所として確保される。使用法は以下のようなものだ。

// リソースディレクトリ内のアプリケーションディスクリプタファイルを指定
file.url = "app-resource:/application.xml";

// ストレージディレクトリ内の、test.dbファイルを指定
file.url = "app-strage:/test.db";

最後に、既存のディレクトリを指すFileオブジェクトから、そのディレクトリ以下のファイルを指すためのメソッドを紹介する。File.resolveメソッドだ。

var cdrive:File = new File("C:\\");

// resolveメソッドを用いて、"TEMP"ディレクトリを取得
var tempDir:File = cdrive.resolve("TEMP");

Fileクラスに定義済みのディレクトリ

Fileクラスは、プラットフォームごとに場所が異なるが、頻繁に利用するディレクトリへの参照を定数として保持している。それらは全て静的にアクセスすることができるFile型のインスタンスだ。以下にその一覧を示す。

  • File.applicationResourceDirectory - アプリケーションリソースディレクトリ
  • File.applicationStrageDirectory - アプリケーションストレージディレクトリ
  • File.desktopDirectory - ユーザのデスクトップを表すディレクトリ
  • File.documentsDirectory - ドキュメントの格納先を表す。Windows環境では「マイドキュメント」となる
  • File.userDirectory - ユーザのホームディレクトリ

Fileクラスが持つ操作

Fileクラスは、ファイルやディレクトリに関する様々な操作をメソッドとして実装している。そうした操作は、呼び出してから完了するまでに時間がかかるものも多いため、メソッド名Asyncという名前の、非同期処理版も用意されている。全てではないが、その一覧を以下に示す。

  • copyTo/copyToAsync - ファイル/ディレクトリをコピーする
  • deleteFile/deleteFileAsync - ファイルを削除する
  • deleteDirectory/deleteDirectoryAsync - ディレクトリを削除する
  • moveTo/moveToAsync - ファイル/ディレクトリを移動する
  • moveToTrash/moveToTrashAsync - ファイル/ディレクトリをゴミ箱に移動する
  • listDirectory/listDirectoryAsync - ディレクトリ内のファイルを全て取得する
  • cancel - まだ実行されていない非同期オペレーションをキャンセルする。

非同期処理を行うメソッドに関しては、FileクラスのaddEventListenerメソッドを用いて、イベントリスナを登録する必要がある。以下のような形だ。

// アプリケーションディスクリプタファイルの取得
var appxml:File = File.applicationResourceDirectory.resolve("application.xml");
// コピー完了時に呼び出されるリスナメソッドを登録
appxml.addEventListener(Event.COMPLETE, function(event:Event):void {
    trace("コピー完了");
});
// デスクトップ上に、同じファイル名でコピー(第二引数をtrueにすると上書きOK)
appxml.copyToAsync(File.desktopDirectory.resolve(appxml.name), true);

// デスクトップを取得
var desktop:File = File.desktopDirectory;
// ファイルのリスト取得が完了したら呼び出されるメソッドを登録
desktop.addEventListener(FileListEvent.DIRECTORY_LISTING, function(event:FileListEvent):void {
    var list:Array = event.files;
    for (var i:uint = 0; i < list.length; i++) {
        trace(list[i].nativePath);
    }
});
// デスクトップ上のファイル一覧を非同期で取得
desktop.listDirectoryAsync();

ファイルのアイコン取得

β版からFileクラスに加わった機能として、OSによって関連付けられているファイルアイコンを取得できるようになった。File.iconプロパティがそれだ。

File.iconプロパティは、flash.desktop.Iconクラスのインスタンスで、16x16や32x32などのサイズに応じたアイコンをbitmapsプロパティに保持している。

// アプリケーションディスクリプタファイルに関連付けられたアイコンを取得
var icon:Icon = File.applicationResourceDirectory.resolve("application.xml");

// アイコンのビットマップデータをループ
for (var i:uint = 0; i < icon.bitmaps.length; i++) {
    // Icon.bitmapsの要素一つ一つはflash.display.BitmapData型
    var bitmapData:BitmapData = BitmapData(icon.bitmaps[i]);

    // flash.display.Bitmap型にしてしまえば、DisplayObjectとして扱えるので扱いやすい
    var bitmap:Bitmap = new Bitmap(bitmapData);
}

まとめ

今回は、AIRにおけるファイル操作の基本となるflash.filesystem.Fileオブジェクトについて解説した。次回は、ファイルを取り扱うためのコンポーネント(ファイル選択ダイアログ、ファイルツリーなど)についてみていきたい。そこでは次のようなサンプルを作成する予定だ。

次回作成するサンプルアプリケーション