Flash Player 10 ではローカルファイルを直接 Flash アプリケーションに読み込んだり Flash アプリケーション内のデータを直接ローカルファイルに書き出す機能が追加されています。
Flash Player 9 でも FileReference を使ってローカルファイルにアクセスすることは可能です。が、その機能はファイルのアップロード/ダウンロードを行うためのもので、Flash アプリケーションからは、一旦サーバを経由しないとローカルファイルのデータを扱うことができませんでした。直接ファイル I/O の出来る日が来ることを心待ちにしていた方も多いことでしょう。
というわけで、Flash Player 10 では flash.net.FileReference クラスに以下の API が追加されています。
public function get data():ByteArray // 読み込まれたデータ (読み取り専用のプロパティ) public function load():void // 指定されたファイルの読み込み開始 public function save(data:*, name:String = null):void // 保存先を選択するダイアログを表示、その後データ保存開始
ファイルの読み込みを開始するには load() メソッドを使用します。読み込むファイルの指定は、browse() メソッドを呼ぶとダイアログが表示されるので、その中でユーザが行います。
このときプログラムから読み込むファイルを指定することはできません。これは SWF がロードされたら勝手にローカルファイルを送信してしまうといった類のアタックからユーザを保護するためです。
load() は呼び出されるとすぐに戻るので、その後の進み具合はイベント経由で確認することになります。このあたりは従来の FileReference の使い方と同じです。
下は、ファイルを読み込む簡単なサンプルです。
var fr:FileReference=new FileReference(); fr.addEventListener(Event.SELECT,onSelect); fr.browse(); // ファイル選択のダイアログを表示 function onSelect(e:Event):void { // イベントリスナーを追加 fr.addEventListener(ProgressEvent.PROGRESS,onProgress); fr.addEventListener(Event.COMPLETE,onComplete); // 下の 2 つはとりあえずコメントアウト // fr.addEventListener(Event.OPEN, onOpen); // fr.addEventListener(IOErrorEvent.IO_ERROR, onIoError); fr.load(); // 読み込み処理を開始 } function onProgress(e:ProgressEvent):void { trace("読み込んだバイト数:" + e.bytesLoaded + "、 全体のバイト数:" + e.bytesTotal); } function onComplete(e:Event):void { trace(fr.data); // fr.type を参考にオブジェクト変換する等の処理を記述 // fr.removeEventListener(...) }
browse() メソッドに対してユーザがファイルを選択すると SELECT イベントが発行されます。上のサンプルではこのタイミングで必要なイベントハンドラを設定して load() を呼び出しています。
読み込み処理が成功すると COMPLETE イベントが発行されます。data プロパティに有効な値が設定されるのはこれ以降です。上の例でも COMPLETE イベントハンドラ内で値を参照しています。
さて、ローカルファイルにデータを保存する場合は save() メソッドを使用します。保存するデータは save() の第一引数に指定します。サポートされるデータの型は以下の 3 種類です。それ以外の型の場合は toString() で変換することで String として扱うようです。
- String : UTF-8 のテキストファイルとして保存
- XML : XML フォーマットで保存
- ByteArray : データをそのまま保存
save() メソッドを呼ぶと、ユーザに保存先を選択するためのダイアログが表示されます。その際、ダイアログ内にデフォルトのファイル名を表示したい場合には save() の第二引数として指定することができます。
var fr:FileReference=new FileReference(); var dat:String ="これは UTF-8 の文字列として保存されます"; fr.addEventListener(Event.COMPLETE,onComplete); fr.save(dat, "UTF8Text.dat"); // ダイアログを表示する function onComplete(e:Event):void { trace(fr.name); // ユーザが指定したファイル名を表示 }
save() では load() の 4 つのイベントに加えて SELECT と CANCEL イベントも利用できます。
例によって、操作するファイルの大きさに制限はありませんが (もちろんメモリが足りないとかは別として)、サポートされる (テストされている) のは 100MB までです。
Flash コンテンツがファイルにアクセスしないように設定したい場合は mm.cfg 内で LocalFileReadDisable を 1 にします。
初めまして大野と申します。
上記の文章に
>>Flash Player 9 でも FileReference を使ってローカルファイルにアクセスすることは可能です。が、その機能はファイルのアップロード/ダウンロードを行うためのもので、Flash アプリケーションからは、一旦サーバを経由しないとローカルファイルのデータを扱うことができませんでした。
とありますが、具体的にどのような方法でアクセスさせているのでしょうか?
お忙しい所、お手数で申し訳ないかもしれませんが、是非教えて頂けないでしょうか?
以上となります。宜しくお願いします。
大野さん、こんにちは。
お返事遅くなり申し訳ありません。
以下のドキュメントに書かれている説明やサンプルのような内容が
知りたいということでしょうか?とりあえず、ご覧ください。
http://livedocs.adobe.com/flash/9.0_jp/ActionScriptLangRefV3/flash/net/FileReference.html
save()が思ったように機能しないのですが、なにかご存じでしょうか?
WinVista+IE7を使用していると、ユーザに保存先を選択するためのダイアログが表示される所までは正常に進みます。
しかし、保存先を選んで「保存」を押すとI/Oエラーになってしまいます。
この状況はswfがオンライン上やネットワークドライブ上にある場合に発生します。ローカルにある場合は正常に動作します。
よろしくお願いします。
【正常な動作する場合】
WinVista+Firefox2
WinVista+IE7(非保護モード)
WinXP+IE7 or IE6 or Firefox3 or Firefox2
【正常に動作しない場合】
WinVista+IE7(保護モード)
大野さん、こんにちは。
連絡が遅くなり申し訳ありませんでした。
ご質問の件ですが、まだ発表前の製品のため仕様をはっきりとお答えすることが難しいです。
お手数ですが、日本語で結構ですので、バグデータベースに登録していただけますでしょうか。
URL は以下になります。
http://bugs.adobe.com/flex/
Flash Player 10 では flash.net.FileReference クラスに追加され、ローカルのテキストファイルのloadなどもできるようになったということで、初心者ながら試行錯誤の上、できるようになりました。とても貴重な情報ありがとうございます。
質問なのですが、アップロードが目的でないのだけれど、このloadを利用したい場合でも、「fr.browse(); 」すると、「(サーバ名)でアップロードするファイルを選択します」と「アップロード」という言葉が必ず入ってしまいます。この文言をカスタマイズする方法は何かあるのでしょうか? サーバ名はセキュリティの関係で非表示にできないのかなと思いつつも、「アップロード」させる意図はないのにこの文言があると、なんか危ないことをさせているように思われないか心配です。
shima さん、こんにちは。
コメントありがとうございます。確認した範囲では、カスタマイズする方法はなさそうでした。
ご指摘のとおり、適切な表現ではないと思いますので、製品チームに伝えるようにします。