前回は、weinreを使ったアプリケーションのデバッグについて紹介しました。今回から、File APIを用いたファイル操作について紹介していきたいと思います。その前に、iOS/Androidのアプリケーション構造や、File APIのオブジェクトについてチェックしておきましょう。
Cordova File APIとは
Cordova File API は、ファイルやディレクトリを操作するためのAPIです。W3C のFile 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オブジェクトについて
操作したいファイルのパスがすでに判明している場合は、window.resolveLocalFileSystemURIでFileSystemオブジェクトを取得し、そこからDirectoryEntry、FileEntry、Fileオブジェクトを取得しながら各操作を行う流れになります。
特定のディレクトリに存在しているファイルを確認しながら処理を行う場合は、window.requestFileSystemでPERSISTENTまたはTEMPORARYのFileSystemオブジェクトを取得し、そこからDirectoryEnterオブジェクトを参照、DirectoryReaderオブジェクトで階層化のファイル・ディレクトリ情報を取得しながら各操作を行う流れになります。
次回は、今回紹介したオブジェクトとDirectoryReader、FileReader、FileWriterオブジェクトを使って実際にファイル・ディレクトリを操作する方法をサンプルアプリケーションを交えながら紹介していきたいと思います。