読者です 読者をやめる 読者になる 読者になる

一汁三菜

インターネットのインフラよりな技術の話題、Web周りの技術的な話題、趣味のマラソン、旅行、その他日々の記録をしています。

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ツリーを生成しています。

ファイルのダウンロード

ファイルのダウンロードには、BlobBlob 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では使いませんでした。

最後に

File API自体は既にそれなりに歴史があり、かつ実際に実用されているケースも多々あります。おかげでFile APIの使い方は様々な書籍やWebサイトで解説されているので、ぜひ他のWebサイトの解説記事も参考にしてみて下さい。

駆け足気味になってしまいましたが、以上で終わりです。