もっと使おうPhoneGap/Cordova 2.0.0

第4回File APIを使ったiOS/Androidアプリケーション作成その1]

前回は、weinreを使ったアプリケーションのデバッグについて紹介しました。今回から、File APIを用いたファイル操作について紹介していきたいと思います。その前に、iOS/Androidのアプリケーション構造や、File APIのオブジェクトについてチェックしておきましょう。

Cordova File APIとは

Cordova File APIは、ファイルやディレクトリを操作するためのAPIです。W3CFile APIに準拠しています。

ファイルの移動や削除を行う処理を実装したい場合、このFile APIを利用します。File APIを紹介する前に、iOSとAndoridのアプリケーション構造について簡単に整理しておきましょう。

iOSアプリケーションの構造について

各アプリケーションには、そのアプリケーション専用のサンドボックスと呼ばれるスペースが与えられます。ファイルの操作が行えるのは自分のサンドボックス内のみで、他のサンドボックスへのアクセスは禁止されています。

サンドボックス内の構造は次のようになっています。

ディレクトリ名 内容
/(アプリ名).app アプリケーション自体を含むバンドルのディレクトリです。このディレクトリに書き込みを行ってしまうと署名が変わり、アプリケーションを起動することができなくなってしまいます
/Documents/ ユーザが作成した情報で、アプリケーションで生成し直すことができないようなデータを格納するためのディレクトリです。ファイル共有機能を使用することで、iTunes経由でファイルの出し入れが可能になります
/Library/ ユーザのデータファイル以外のファイルを格納するためのディレクトリです。ユーザのデータファイル格納に使用してはいけません。PhoneGapアプリケーションでは、このLibrary以下にwwwディレクトリが作成され、その中身がUIWebViewで描画されます
/tmp/ アプリケーションを次に起動するまで保持する必要ない、一時的なファイルを格納するためのディレクトリです。システムにより、特定のタイミングでファイルが勝手に削除されます。Cordova Camera APIやCordova Capture APIで撮影・録音・録画したデータは、一時的にこのtmpディレクトリに保存されます
サンドボックスの構造FileSystemProgrammingGuide.pdfより引用)
サンドボックスの構造

Androidアプリケーションの構造について

各アプリケーションには独自のプロセス上で実行され、ユーザIDが割り当てられます。Linuxのパーミッション概念を利用し、サンドボックス外のリソースは禁止されています。連絡先やSMSなどのシステムリソースにアクセスしたい場合は、あらかじめマニフェストを定義しておく必要があります。

ディレクトリ名 内容
/data/app/(アプリケーション名).apk アプリケーションのパッケージファイルが格納されるディレクトリです
/mnt/sdcard/ 内蔵ストレージを参照しているディレクトリです
/mnt/sdcard/Android/data/(アプリケーション名)/cache/ 一時的なファイルを格納するためのディレクトリです

これらを前提にして、File APIを紹介してきましょう。

File APIのオブジェクト─分類

File APIで用意されているオブジェクトは15種類です。簡単に整理してみましょう。

分類 オブジェクトの種類
ファイルシステム、ディレクトリ、ファイルの読み込み LocalFileSystem, DirectoryReader, FileReader
ファイルシステム、ディレクトリ、ファイルの情報 FileSystem, DirectoryEntry, FileEntry, File
ファイルの書き込み FileWriter
属性、メタデータ Flags, Metadata
ファイル転送に関するオブジェクト FileTransfer, FileUploadOptions, FileUploadResult
エラーオブジェクト FileError, FileTransferError

PhoneGapで用意されているファイルシステム、ディレクトリ、ファイルを読み込むメソッドは、すべて非同期で動作します。このため、メソッドの引数でコールバック関数を指定する必要があります。

File APIでファイルを操作するにあたり、順を追って確認してみましょう。

ファイルシステムについて

File APIで取り扱うファイルシステムは、おもに2種類─PERSISTENTとTEMPORARYです。PERSISTENTは、アプリケーションまたはユーザの許可なしに、ユーザエージェントによって削除されるべきではないストレージを指します。TEMPORARYは、永続性の保証がないストレージを指します。

iOSとAndroidにおいて、PERSISTENTとTEMPORARYに相当するディレクトリ位置は次のとおりです。

  PERSISTENT TEMPORARY
iOS /private/var/mobile/Applications/
(アプリケーション固有のID)/Documents/
/private/var/mobile/Applications/
(アプリケーション固有のID)/tmp/
Android /mnt/sdcard/ /mnt/sdcard/Android/data/
(アプリケーション名)/cache/

LocalFileSystemオブジェクトに用意されている次の2つのメソッドで、FileSystemオブジェクトを取得します。(LocalFileSystemオブジェクトのメソッドは、windowオブジェクトで定義されています)

window.requestFileSystemでは、PERSISTENTまたはTEMPORARYのどちらかのFileSystemオブジェクトを取得します。

// cordova-2.0.0.js 4884-4891
/**
 * Request a file system in which to store application data.
 * @param type  local file system type
 * @param size  indicates how much storage space, in bytes, the application expects to need
 * @param successCallback  invoked with a FileSystem object
 * @param errorCallback  invoked if error occurs retrieving file system
 */
var requestFileSystem = function(type, size, successCallback, errorCallback) {

引数は次のとおりです。

type 取得したいファイルシステムの種類を、定数で指定します。PERSISTENTの場合はLocalFileSystem.PERSISTENTを、TEMPORARYの場合はLocalFileSystem.TEMPORARYを指定します
size アプリケーションで必要となるストレージの容量を、バイト単位で指定します
successCallback FileSystemオブジェクト取得成功時のコールバック関数を指定します
errorCallback FileSystemオブジェクト取得失敗時のコールバック関数を指定します

window.resolveLocalFileSystemURIでは、URIを使ってFileSystemオブジェクトを取得します。

// cordova-2.0.0.js 4929-4935
/**
 * Look up file system Entry referred to by local URI.
 * @param {DOMString} uri  URI referring to a local file or directory
 * @param successCallback  invoked with Entry object corresponding to URI
 * @param errorCallback    invoked if error occurs retrieving file system entry
 */
module.exports = function(uri, successCallback, errorCallback) {

引数は次のとおりです

uri ローカルファイルまたはディレクトリへのパスをURIで指定します
successCallback FileSystemオブジェクト取得成功時のコールバック関数を指定します
errorCallback FileSystemオブジェクト取得失敗時のコールバック関数を指定します

取得したFileSystemオブジェクトには、2つのプロパティが含まれます。

name
ファイルシステムの名前が文字列型で格納されます
root
ファイルシステムのルートディレクトリが、DirectoryEntryオブジェクトとして格納されます

DirectoryEntryオブジェクトについて

DirectoryEntryオブジェクトは、ディレクトリそのものを指します。

DirectoryEntryオブジェクトのプロパティは次のとおりです。

  • isFile:常にfalseが返ります
  • isDirectory:常にtrueが返ります
  • name:ディレクトリ名が格納されています
  • fullPath:ルートからの絶対パスが格納されています

なお、W3Cの仕様ではfilesystemプロパティが定義されていますが、Cordovaではサポートされていません。

DirectoryEntryオブジェクトに用意されているメソッドは次のとおりです。(使い方のdirectoryEntryは、DirectoryEntryオブジェクトを指します)

メソッド名 内容
使い方
getMetadata ディレクトリのメタデータを取得します。
  • 成功時、successCallbackに、取得したメタデータをMetadataオブジェクトとして渡します。
  • 失敗時、errorCallbackに、FileErrorオブジェクトを渡します。
directoryEntry.getMetadata(successCallback, errorCallback);
setMetadata ディレクトリにメタデータを設定します。
  • 第3引数にMetadataオブジェクトを指定して、メタデータを設定します。
  • Cordova 2.0.0時点では、iOSでのみ動作します。
directoryEntry.setMetadata(successCallback, errorCallback, metadataObject);
moveTo ディレクトリを移動します。
  • 移動先のディレクトリは、DirectoryEntryオブジェクトで指定します。
  • ディレクトリ名は、第2匹数で変更できます。(初期値は現在の名前)
  • 成功時、successCallbackにDirectoryEntryオブジェクトを渡します。
  • 失敗時、errorCallbackにFileErrorオブジェクトを渡します。
directoryEntry.moveTo(parent, newName, successCallback, errorCallback);
copyTo ディレクトリをコピーします。引数はmoveToメソッドと同じです。
directoryEntry.copyTo(parent, newName, successCallback, errorCallback);
toURL ディレクトリの場所をURLで返します。返り値は文字列型です。
var directoryURL = directoryEntry.toURL();
remove ディレクトリを削除します。
  • あらかじめディレクトリの中がからっぽである必要があります。
  • ルートディレクトリは削除できません。
  • 失敗時、errorCallbackにFileErrorオブジェクトを渡します。
directoryEntry.remove(successCallback, errorCallback);
getParent 親ディレクトリの情報を取得します。
  • 成功時、successCallbackに、親ディレクトリの情報をDirectoryEntryオブジェクトとして渡します。
  • 失敗時、errorCallbackに、FileErrorオブジェクトを渡します。
directoryEntry.getParent(successCallback, errorCallback);
createReader ディレクトリ内のファイルを読み込むためのオブジェクト、DirectoryReaderオブジェクトを生成します。返り値はDirectoryReaderオブジェクトです。
var directoryReader = directoryEntry.createReader();
getDirectory ディレクトリ内に存在するディレクトリの情報を取得します。
  • optionsにはFlagsオブジェクトでオプションを指定します。特定の引数を渡すことで、新規にディレクトリを作成します。
  • 成功時、successCallbackに、DirectoryEntryオブジェクトを渡します。
  • 失敗時、errorCallbackに、FileErrorオブジェクトを渡します。
directoryEntry.getDirectory(path, options, successCallback, errorCallback);
getFile ディレクトリ内に存在するファイルの情報を取得します。
  • optionsにはFlagsオブジェクトでオプションを指定します。特定の引数を渡すことで、新規にファイルを作成します。
  • 成功時、successCallbackに、FileEntryオブジェクトを渡します。
  • 失敗時、errorCallbackに、FileErrorオブジェクトを渡します。
directoryEntry.getFile(path, options, successCallback, errorCallback);
removeRecursively ディレクトリを再帰的に削除します。
  • ルートディレクトリは削除できません。
  • 失敗時、errorCallbackにFileErrorオブジェクトを渡します。
directoryEntry.removeRecursively(successCallback, errorCallback);

FileEntryオブジェクトについて

FileEntryオブジェクトは、 ファイルそのものを指します。

FileEntryオブジェクトのプロパティは次のとおりです。

  • isFile:常にtrueが返ります
  • isDirectory:常にfalseが返ります
  • name:ファイル名が格納されています
  • fullPath:ルートからの絶対パスが格納されています

DirectoryEntryと同様、W3Cの仕様ではfilesystemプロパティが定義されていますが、Cordovaではサポートされていません。

FileEntryオブジェクトに用意されているメソッドは次のとおりです(使い方のfileEntryは、FileEntryオブジェクトを指します⁠⁠。

メソッド名 内容
使い方
getMetadata ファイルのメタデータを取得します。
  • 成功時、successCallbackに、取得したメタデータをMetadataオブジェクトとして渡します。
  • 失敗時、errorCallbackに、FileErrorオブジェクトを渡します。
fileEntry.getMetadata(successCallback, errorCallback);
setMetadata ファイルにメタデータを設定します。
  • 第3引数にMetadataオブジェクトを指定して、メタデータを設定します。
  • Cordova 2.0.0時点では、iOSでのみ動作します。
fileEntry.setMetadata(successCallback, errorCallback, metadataObject);
moveTo ファイルを移動します。
  • 移動先のディレクトリは、DirectoryEntryオブジェクトで指定します。
  • ファイル名は、第2匹数で変更できます。(初期値は現在の名前)
  • 成功時、successCallbackにFileEntryオブジェクトを渡します。
  • 失敗時、errorCallbackにFileErrorオブジェクトを渡します。
fileEntry.moveTo(parent, newName, successCallback, errorCallback);
copyTo ファイルをコピーします。引数はmoveToメソッドと同じです。
fileEntry.copyTo(parent, newName, successCallback, errorCallback);
toURL ファイルの場所をURLで返します。返り値は文字列型です。
var fileURL = fileEntry.toURL();
remove ファイルを削除します。
  • 失敗時、errorCallbackにFileErrorオブジェクトを渡します。
fileEntry.remove(successCallback, errorCallback);
getParent 親ディレクトリの情報を取得します。
  • 成功時、successCallbackに、親ディレクトリの情報をDirectoryEntryオブジェクトとして渡します。
  • 失敗時、errorCallbackに、FileErrorオブジェクトを渡します。
fileEntry.getParent(successCallback, errorCallback);
createWriter ファイルを書き込むのオブジェクト、FileWriterオブジェクトを生成します。返り値はFileWriterオブジェクトです。
var fileWriter = fileEntry.createWriter();
file 単一ファイルの情報を格納するFileオブジェクトを取得します。
  • 成功時、successCallbackに、Fileオブジェクトを渡します。
  • 失敗時、errorCallbackに、FileErrorオブジェクトを渡します。
fileEntry.file(successCallback, errorCallback);

Fileオブジェクトについて

Fileオブジェクトは、単一ファイルの情報を格納しています。メソッドは用意されていません。

Fileオブジェクトのプロパティは次のとおりです。

  • name:ファイル名が格納されています
  • fullPath:ルートからの絶対パスが格納されています
  • type:MIMEタイプが格納されています
  • lastModifiedDate:最終更新日時が格納されています
  • size:ファイルサイズが格納されています

FileSystem、DirectoryEntry、FileEntry、Fileオブジェクトのそれぞれの関係性を次に示します。

FileSystem、DirectoryEntry、FileEntry、Fileオブジェクトについて
FileSystem、DirectoryEntry、FileEntry、Fileオブジェクトについて

操作したいファイルのパスがすでに判明している場合は、window.resolveLocalFileSystemURIでFileSystemオブジェクトを取得し、そこからDirectoryEntry、FileEntry、Fileオブジェクトを取得しながら各操作を行う流れになります。

特定のディレクトリに存在しているファイルを確認しながら処理を行う場合は、window.requestFileSystemでPERSISTENTまたはTEMPORARYのFileSystemオブジェクトを取得し、そこからDirectoryEnterオブジェクトを参照、DirectoryReaderオブジェクトで階層化のファイル・ディレクトリ情報を取得しながら各操作を行う流れになります。

次回は、今回紹介したオブジェクトとDirectoryReader、FileReader、FileWriterオブジェクトを使って実際にファイル・ディレクトリを操作する方法をサンプルアプリケーションを交えながら紹介していきたいと思います。

おすすめ記事

記事・ニュース一覧