File API
File APIはファイルの読み書きができるAPIですが、読み込みは input type="file" にて指定されたファイルを読み込む機能で、書き込みはWebブラウザのダウンロードにデータを渡す(またはObjectURLを生成)機能となっています。任意のファイルにアクセスしたり、書き込みができる訳ではありません。
利用できるかの判別
ファイル読み込みができるかどうかは以下のコードで判別ができます。
これがtrueであれば利用できます。
ファイルの読み込み
例えばHTMLが以下のように指定されていたとします。
multiple 指定をしているので複数ファイルを選択できます。
さらにここでファイルを指定した場合のイベントハンドラを登録します。
document.querySelector("#file").addEventListener('change', file_changeHandler);
}
こうするとファイルを指定した時点で file_changeHandler が呼ばれるようになります。
var file = evt.target.files[0];
var reader = new FileReader();
reader.onload = function(event) {
console.log(event.target.result);
}
reader.readAsText(file);
}
FileReaderのオブジェクトに readAsText としてファイル(テキスト)を渡しています。そのreaderのonloadを通じてファイルの内容が読み込まれる仕組みです。非同期で読み込み処理が行われるので注意してください。
readAsTextはテキストファイルの読み込みに使います。その他にも次のようなメソッドがあります。
readAsBinaryString(File)
バイナリファイルを読み込みます。
readAsDataURL
ファイルを読み込むのは変わりませんが、Data URIにエンコードされたデータを返します。
readAsArrayBuffer
ArrayBufferオブジェクトとしてデータを返します。
なお、readAsTextはエンコード指定も可能です(デフォルトはUTF-8になります)。ただしエンコードの自動判別はできません。
Data URIを使ったパターン
Data URIを使った場合、画像のsrcなどにそのまま文字列として当てはめられるのがメリットです。
var file = evt.target.files[0];
var reader = new FileReader();
reader.onload = function(event) {
var image = new Image();
image.src = event.target.result;
}
reader.readAsDataURL(file);
}
readAsBinaryString を使ったパターン
readAsBinaryString を使った場合、 event.target.result はバイナリデータがそのまま入ります。かつ、1バイトが1文字のデータになりますので、charAtなどのString向けのメソッドがそのまま利用できます。
readAsArrayBuffer を使ったパターン
readAsArrayBufferはArrayBufferを返却しますが、ArrayBufferはそのままでは扱いません。Uint8Arrayなどを使って配列に変換します(Uint8Arrayは8ビットで符号無し整数に変換)。
ファイルの書き込み
ファイルの書き込みを行う場合、まずは Blob を生成します。
text で指定した部分が保存する文字列になります。そして blob をObjectURLに変換します。
-> "blob:http%3A//example.com/b230d7b2-4cdf-4bdc-bf26-29a396475c52"
そうするとこのような文字列が返ってきます。このURLを開くとtextで指定した文字列が書き込まれたファイルが表示されます。
IEの場合は
のようにすることでファイルの保存ができるようになっています。
このようにファイル書き込みについてはブラウザの挙動が異なるほか、元々BlobBuilderだったのがBlobになったりと、動向が安定しないようです。