File APIとその実例
HTML5 Advent Calendar 2012からお越しの皆様、こんにちは。11日目を担当させていただきます。よろしくお願いします。
今回は、File APIを取り上げたいと思います。File APIとはクライアントのローカルにあるファイルの読み込みや書き込みをサポートするAPIです。主に出来ることとしては、
- ローカルにあるファイルをブラウザ上にドラッグ&ドロップ
- ローカルにあるファイルの読み込み
- Javascriptでファイルを生成してダウンロードさせる
- (ローカルにあるファイルの書き込み)
File APIは巷に出回っている主要なWebブラウザの最新版では概ね対応されています。
今回、File APIを使って自分が作成したWebアプリケーションである "morpwx" を例にして、File APIがどのような挙動をするのかを見ていきます。
morpwxの紹介
morpwxは、TrainingPeaksというWebサイトや、Timex製のGPS時計で採用されているPWXという形式のファイル操作するライブラリです。ソースコードはGitHubで公開しています。そのサンプル第一号として、PWXファイルをendomondoやGarminで採用されているTCXという形式のファイルに変換するWebアプリケーションを作りました。jsdo.itで実際に動くサンプルを公開しています。このサンプルの中で、File APIを利用しました。
ドラッグ&ドロップ
ファイルのドラッグ&ドロップは、ondropイベントとondragoverイベントで行います。ondragoverイベントはドロップ可能なファイルが当該要素の上にある時に呼び出されるイベントです。ondropイベントは、ファイルがドロップされた時に呼び出されるイベントです。
でも本来、ローカルにあるファイルがWebブラウザの上にドロップされた場合、ブラウザはそのファイルを表示するはずです。そうしない為には、イベントハンドラのイベントオブジェクトにあるpreventDefault()を呼び出します。こうすると、ブラウザはファイルを表示するのをやめます。
function ondrop(event) { // いろいろやる event.preventDefault(); }
ドロップされたファイルの情報を取得する
まずはドロップされたファイルの情報を取得してみます。
function ondrop(event) { var files = event.dataTransfer.files; event.preventDefault(); }
filesは配列になっていて、Fileインターフェースのオブジェクトが入っています。files中のオブジェクトは以下のような構造になっています。
プロパティ名 | 型 | 説明 |
---|---|---|
name | DomString | ファイル名 |
size | unsigned long long | ファイルサイズ |
type | DOMString | MIMEタイプ |
lastModifiedDate | Date | 最終更新日時 |
ファイルの読み込み
ファイルの読み込みはFileReaderを利用します。onloadプロパティに読み込んだデータを処理するコールバックメソッドを指定して、読み込みたい形式に応じたメソッドを呼び出します。
readAsText()は、読み込んだデータをテキスト形式で取得します。readAsArrayBuffer()はArrayBuffer(バイナリ値の配列)が得られます。readAsDataURL()は、data URI形式で得られます。data URIで取得すると、そのままimg要素のsrc属性に放り込めたりするので、結構便利です。
読み込んだデータは、イベントオブジェクトを通じて取得します (event.target.result)。
morpwxでは、ドロップされたXMLファイルを変換したかったので、readAsText()によってテキスト形式でファイルの中身を取得した後に、DOMParserのparseFromString()を使ってDOMツリーを生成しています。
ファイルのダウンロード
ファイルのダウンロードには、BlobとBlob URIを使いました。ここでのBlobは、乱暴に言ってしまえば「ファイル名の無いファイル」のような物です。実はここまででも導入無しに何度か使っています。生成したBlobに対してwindow.URL.createObjectURL()を使うと、そのBlobを指し示すURIが生成されます。これをa要素のhref属性に指定することで、あたかもファイルのダウンロードをしているかのように見せかける事ができます。
var blob = new Blob([data]); var blobURL = (window.URL || window.webkitURL).createObjectURL(blob); // Webkitではまだvendor prefixがつく var aElem = document.getElementById("something_anchor"); aElem.setAttribute("href", blobURL);
morpwxでは、PWXファイルを変換して得られたTCXファイルをダウンロードする為に、この一連の機構を使いました。
ファイルの書き込み
W3CのFile APIの規格には含まれていませんが、FileReaderと対をなすFileWriterも別立てで仕様が検討されています。
サポートされているWebブラウザが少ないので、今回morpwxでは使いませんでした。