ファイルの一覧を取得する
では、実際にAPIを使っていきます。まずは、指定したディレクトリからファイルもしくはディレクトリの一覧を取得します。
リスト4はwwwディレクトリ以下にあるファイルもしくはディレクトリ一覧を取得する場合のサンプルコードです。
// (1) URLを使ってパスを指定
window.resolveLocalFileSystemURL(
cordova.file.applicationDirectory + "www",
// (2) Entry(DirectoryEntry)の取得に成功した場合
function(entry){
// (3) ファイル一覧を取得する為の
var reader = entry.createReader();
reader.readEntries(function(entries){
// $applyはAngularJSに変更を伝える為
$scope.$apply(function(){
// (4) 指定したディレクトリ以下のファイル、もしくはディレクトリの一覧が取得できる
$scope.files = entries;
});
},function(error){
window.alert("読込失敗 :" + error.code);
});
},
// (5) 失敗した場合
function(error){
var message = "unknown";
switch(error.code){
case FileError.NOT_FOUND_ERR:
message = "ファイルが見つかりません";
break;
default:
message = "その他エラー";
break;
}
window.alert("読込失敗 :" + error.code + " - " + message);
}
);
(1)ではwindow.resolveLocalFileSystemURL()メソッドを使って指定のURLからファイル、もしくはディレクトリの情報を取得します。URLを指定する場合には、先ほど説明したcordova.fileオブジェクトのプロパティを使ってURLを作成します。
今回は、アプリケーションデータ(applicationDirectory)配下のwwwディレクトリの情報を取得したいので、「cordova.file.applicationDirectory + "www"」でパスを取得しています。
取得に成功すると、引数にEntryオブジェクトを引数としてsuccessCallbackが実行されます(2)。
指定したパスはディレクトリなので、Entryオブジェクトの実体はDirectoryEntryになります。DirectoryEntryオブジェクトが取得できたら、(3)のように、そのオブジェクトのcreateReaderメソッドでDirectoryReaderオブジェクトを作成し、readEntriesメソッドを使って、指定のディレクトリ配下にあるFileEntryもしくはDirectoryEntryが格納された配列を取得します。
(4)ではAngularJSでHTMLテンプレート側で使えるように変数を設定しています。scope.$applyというメソッド内部で値を設定しているのは、AngularJSでHTML表示側に設定した値を反映させるためです。AngularJSを利用していない場合には、あまり気にする必要はありません。
(5)はエラーの場合の処理です。エラー原因はcodeプロパティの値で判断をします。File System APIではエラーがあったときには、codeプロパティにエラー番号が設定されます。このエラー番号はFileErrorの定数として定義されていますので、その定数を利用し原因を特定します。
エラー時には共通してこのエラー番号にて処理をしますので、実際に利用する際にはある程度、共通化した方が良いでしょう。
| 定数 | 説明 |
|---|---|
| NOT_FOUND_ERR | ファイルもしくはディレクトリが見つからなかった場合 |
| SECURITY_ERR | セキュリティ上の理由などにより操作できなかった場合 |
| ABORT_ERR | 処理がなんらかの理由により中断された場合 |
| NOT_READABLE_ERR | 読込権限がない場合 |
| NO_MODIFICATION_ALLOWED_ERR | ファイルへの書込ができなかった場合 |
| INVALID_MODIFICATION_ERR | ファイルへの変更要求が受け付けられなかった場合 |
| PATH_EXISTS_ERR | すでに指定されたパスが存在している場合 |
| ENCODING_ERR | URLが不正な場合 |
| TYPE_MISMATCH_ERR | ファイルタイプが異なる場合 |
| QUOTA_EXCEEDED_ERR | 規定したストレージ領域が足りなくなった場合 |
図3はサンプルを実行した時の結果です。
またその時のHTMLテンプレートをリスト5に示します。ng-repeatというのはAngularJSで繰り返してDOM要素を表示する時に利用する属性指定です。
この指定によって、$scope.filesの配列分だけ繰り返して表示することができます。
<div>
<h2>ディレクトリの読込</h2>
<div class="list-group">
<!-- $scope.filesの配列分だけ以下を繰り返して表示する。 -->
<div class="list-group-item" ng-repeat="item in files">
<span class="glyphicon glyphicon-folder-close" aria-hidden="true" ng-show="item.isDirectory"></span>
<span class="glyphicon glyphicon-file" aria-hidden="true" ng-show="item.isFile"></span>
<span>{{item.name}}</span>
</div>
</div>
</div>
ファイルの内容を読む
ファイルの情報が取得できるようになったので、続いて実際のファイルの内容を読んでみましょう。サンプルではwww配下のファイルを扱っていますが、その場合にはFileSystem APIを使わなくてもajaxなどを使って読むことはできます。よって、一般的には、別の領域(dataDirectory)に保存したファイルなどを読むことが多いかもしれません。その場合には、パスを変えれば問題ありません。
ファイルの内容を読むためのコードは、リスト6のようになります。
// (1) FileEntryを取得する
window.resolveLocalFileSystemURL(
cordova.file.applicationDirectory + "www/json/labels.json",
function(entry){
// (2) Fileオブジェクトを取得する
entry.file(function(file){
// (3) FileReaderを使って内容を読む
var reader = new FileReader();
reader.onload = function(e){
$scope.$apply(function(){
$scope.text = e.target.result;
})
};
// (4) テキストとしてデータを読みこむ
reader.readAsText(file);
});
},
function(error){
window.alert("読込失敗 :" + error.code + " - " + message);
}
);
(1)では前回と同様に、window.resolveLocalFileSystemURLメソッドを使い、FileEntryオブジェクトを取得します。ここではサンプルの都合上、あらかじめwwwディレクトリに用意しておいたファイルを指定しています。
(2)のように取得したFileEntryオブジェクトのfileメソッドを用いると、Fileオブジェクトが取得できます。このFileオブジェクトはFormのFileコントロールを使って取得したFileオブジェクトと同じものです。
従って、(3)のようにFileReaderを使って内容を参照することができます。今回は、テキストデータですので、(4)のようにreadAsTextメソッドを使ってファイルのデータを読みこみます。
例えば、読みこむデータが画像の場合には、readAsDataUrlなどを使います。
最後に
今回は主に、ファイルを参照する操作について説明をしましたが、次回も引き続き、cordova-plugin-fileプラグインを使ってファイルの作成や書き込みの説明をします。
ファイル操作ができるとWebアプリではできなかったことが、いろいろとできるようになります。特にハイブリッドアプリであれば、実際にはデータはサーバ側にあるケースが多いと思いますが、そのデータをダウンロードしておき、オフラインになっても利用できるようにするなどの使い方も可能です。
また、Cordovaは既にHTML5として用意されているAPIがあればできるだけそのAPIと同じインターフェースを使って機能を実装しています。これらは既にそれらの知識があるエンジニアに取ってはわかりやすいのではないかと思います。
