今回はFileReaderオブジェクトを使って、これまでに作成した画像ファイルとテキストファイルを読み込む手順を紹介していきます。
FileReaderオブジェクトを使ったファイルロード
PERSISTENTファイルシステムのファイル一覧を表示し、ファイル名をクリックして、ファイル内のデータを表示するアプリケーションを作成してみましょう。
新たに登場するオブジェクトとメソッドは次のとおりです。
- FileReaderオブジェクト
- readAsDataURLメソッド
- readAsTextメソッド
これまでと同様、実機を使用せずにMac OS上のiOSシミュレータ、Windows上のAndroidエミュレータとPCに接続されているカメラデバイスを用いた手順を紹介します。
PERSISTENTファイルシステムのファイル一覧を表示。ファイル名をクリックして、ファイル内のデータを表示(iOS/Android)
PERSISTENTファイルシステムのファイル一覧を表示し、ファイル名をクリックすることでファイルの中身が表示されるサンプルを作成します。これまでのサンプルでは、PERSISTENTファイルシステムに画像ファイルまたはテキストファイルが書き込まれます。画像の場合はその画像を表示、テキストファイルの場合は、テキストファイルの中身を表示します。
テスト用のソースコードは次のとおりです。
まずはiOSで実行してみましょう。アプリケーションを起動すると、PERSISTENTファイルシステムに格納されているファイルの一覧が<ul><li>要素で表示されます。DirectoryEntry/FileEntryに用意されているisFileプロパティを参照し、ファイルのみを対象としています。
ファイル名をクリックすると、ファイルの詳細が表示されます。画像ファイルの場合は画像が、テキストファイルの場合はテキストデータを画面に表示します。
iOSシミュレータでファイルを取り扱うアプリケーションを作成する場合、XcodeのデバッグログにBase64エンコードされたファイルデータを書き出す影響で、動作が遅くなります。スキーマの編集画面を開き、Build ConfigurationをDebugからReleaseにすることで、動作速度を向上させることができます。
具体的な手順は次のとおりです。
- Xcodeの対象プロジェクトを選択している状態で、上部メニューの[Product]より[Edit Scheme]をクリック
- Build Condigurationのプルダウンを選択し、[Debug]から[Release]に変更
- 右下の[OK]ボタンをクリック
Build Configurationを変更することで、トラブルの原因切り分けに必要なログも出力されなくなる場合もあります。トラブルの原因を切り分ける作業を行う際は、再度Debugに戻しておくと良いでしょう。
続いて、Androidで実行してみましょう。
このサンプルコードでは、おもに2画面─ファイル名を列挙する<ul><li>要素と、ファイルの詳細を表示する<div id="viewer">要素から成り立ちます。<div id="viewer">要素はアプリケーション起動時の際には非表示とし、ファイル名をクリックすることではじめて見えるようになります。行っている処理の流れは次のとおりです。
- requestFileSystemでPERSISTENTファイルシステムを取得
- FileSystemオブジェクトのrootプロパティから、PERSISTENTファイルシステムのルートディレクトリの情報(DirectoryEntryオブジェクト)を取得
- DirectoryEntryオブジェクトのcreateReaderメソッドを用いて、DirectoryReaderオブジェクトを作成
- DirectoryReaderオブジェクトのreadEntriesメソッドを用いて、ディレクトリ内のファイル/ディレクトリエントリを読み込む
- readEntriesメソッドから渡されたFileEntry/DirectoryEntryの配列を受け取り、ファイルのみを<li>要素で列挙。ファイル名をクリックすることでFileEntryオブジェクトを取得するように
- FileEntryオブジェクトからFileオブジェクトを取得
- FileReaderオブジェクトを作成。Fileオブジェクトと組み合わせて、ファイルデータを読み込み、ファイル情報と一緒に画面に表示する
PERSISTENTファイルシステム内のファイルを列挙するところまでは、前回のサンプル「TEMPORARYファイルシステムのファイル一覧を取得」とほぼ一緒です。DOMを挿入する前に、addEventListenerでファイル名がクリックされた際にviewFileEntry関数が呼び出されるようにしておきます。
viewFileEntry関数は、FileEntryオブジェクトを取得するための関数です。textContentプロパティからファイル名を取得し、PERSISTENTファイルシステムのDirectoryEntryオブジェクトからgetFileメソッドを使い、FileEntryオブジェクトを取得します。
71行目のgetFileメソッドの第3引数に指定しているgetFile関数では、FileEntryからFileオブジェクトを取得します。
76行目のfileメソッドの第1引数に指定しているreadFile関数は、Fileオブジェクトを使用してファイルを読み込みます。関数の先頭でFileReaderオブジェクトを作成します。その後、Fileオブジェクトのname, sizeプロパティからそれぞれファイル名, ファイルサイズを取得し、それぞれのDOM要素に挿入します。
FileReaderオブジェクトのプロパティは次のとおりです。
- readyState:
- EMPTY(0: 何も読み込んでいない), LOADING(1: 読み込み中), DONE(2: 読み込み完了)のうち、いずれかの状態を示します
- result:
- readAsDataURLメソッド, readAsTextメソッドで読み込んだファイルのデータを格納します
- error:
- エラー発生時にFileErrorオブジェクトを格納します
- onloadstart:
- イベントハンドラ。ファイルのロード開始時に呼び出したい関数を指定します
- onprogress:
- イベントハンドラ。ファイルのロード中に呼び出したい関数を指定します。現在サポートされていない機能です
- onload:
- イベントハンドラ。ファイルのロード完了時に呼び出したい関数を指定します
- onabort:
- イベントハンドラ。ファイルのロード中止時に呼び出したい関数を指定します
- onerror:
- イベントハンドラ。ファイルロード失敗時に呼び出したい関数を指定します
- onloadend:
- イベントハンドラ。ファイルロードの成功/失敗問わずにリクエストが完了した際に呼び出したい関数を指定します
FileReaderオブジェクトに用意されているメソッドは次のとおりです(使い方のfileReaderは、FileReaderオブジェクトを指します)。
メソッド名 |
内容 |
使い方 |
abort |
ファイルの読み込みを中止します。 |
fileReader.abort() |
readAsDataURL |
ファイルを読み込み、データURL形式でresultプロパティに格納します。
- 引数に読み込みたいFileオブジェクトを指定します。
|
fileReader.readAsDataURL(file) |
readAsText |
ファイルを読み込み、resultプロパティに格納します。
- 第1引数には読み込みたいFileオブジェクトを指定します。
- 第2引数にはエンコーディングを指定します。デフォルト値はUTF-8、省略可能です。iOSではこの引数はサポートされておらず、常にUTF-8エンコーディングとなります。
|
fileWriter.readAsText(file, encoding) |
コードの解説に戻ります。ここでは続けてファイルタイプの判定を行っています。Androidの場合はFileオブジェクトのtypeプロパティから、ファイルのMIMEタイプを判定します。iOSの場合はtypeプロパティがnullとなってしまったので、ファイル名の拡張子からファイルが画像であるか否かを判定します。
ファイルが画像(jpg)の場合は、FileReaderオブジェクトのreadAsDataURLメソッドを用いてファイルを読み込みます。引数に指定するのは、読み込みたいFileオブジェクトです。readAsDataURLメソッドでは、引数に指定したFileオブジェクトをデータURL形式で読み込みます。データURL形式の文字列をそのまま<img>要素のsrc属性に格納することで、画像を描画することができます。
FileReaderオブジェクトに用意されているonloadendイベントをもちいて、ファイルの読み込みが完了した時点で無名関数を呼び出します。ファイル名の列挙を非表示とし、ファイル情報の詳細を表示するための<div id="viewer">要素を可視化します。Imageオブジェクトを作成し、srcプロパティにreadAsDataURLメソッドで取得したデータURL形式の文字列を代入し、appendChildメソッドでDOMを挿入して画像を表示します。
ファイルがテキスト(txt)の場合は、FileReaderオブジェクトのreadAsTextメソッドを用いてファイルを読み込みます。readAsDataURLメソッド同様、引数に指定するのは、読み込みたいFileオブジェクトです。readAsTextの場合は、引数に指定したFileオブジェクトをテキスト形式で読み込みます。
FileReaderオブジェクトに用意されているonloadendイベントをもちいて、ファイルの読み込みが完了した時点で無名関数を呼び出します。ファイル名の列挙を非表示とし、ファイル情報の詳細を表示するための<div id="viewer">要素を可視化。<div id="fileContents">要素に読み込んだテキストデータを挿入し、white-spaceスタイルにpreを指定してテキストデータを表示させます。
back関数はファイル情報詳細画面から一覧画面に戻るための関数です。ファイル情報が格納されている要素を初期化し、<ul id="fileList">を可視化。<div id="viewer">を非表示にします。
昨今ではJavaScriptでバイナリを操作するオープンソースのライブラリもいくつか登場してきています。速度の面を突き詰めると各デバイス向けのネイティブアプリケーションを実装するのがベストですが、Webの開発リソースを活かしながらデバイス上のファイル操作も行えるPhoneGapは、条件が一致すれば強力な開発プラットフォームとなるでしょう。
次回はファイル転送に関係するオブジェクトの紹介と、FileTranferオブジェクトを利用したファイルのアップロード、ダウンロードを行うサンプルアプリケーションを取りあげます。