JavaScriptでローカルファイルを自在に操る - File API

TIPS 056:バイナリファイルを読み込む(2)
FileReaderオブジェクトには、もうひとつバイナリファイルを読み込むための
readAsBinaryStringメソッドが用意されています。
例えば以下は、TIPS 055のサンプルをreadAsBinaryStringメソッドで書き換えたものです。
[リスト04]画像ファイルの内容を表示(readBinary.html)
<script>
window.addEventListener('DOMContentLoaded', function() {
// ファイルが指定されたタイミングで、その内容を表示
document.querySelector("#file").addEventListener('change', function(e) {
// File APIを利用できるかをチェック
if (window.File) {
// 指定されたファイルを取得
var input = document.querySelector('#file').files[0];
// ファイル読み込みの準備
var reader = new FileReader();
// ファイルの読み込みに成功したら、その内容を<img id="result">に反映(2)
reader.addEventListener("load", function(event){
// バイナリデータを取得
var raw = reader.result;
// バイト配列を格納する変数
var bytes = [];
// バイナリデータを順に取得(0xffとの論理積でバイト値に変換(1))
for (var i = 0; i < raw.length; i++){
bytes[i] = raw.charCodeAt(i) & 0xff;
}
// Base64エンコードしたものをData URL形式に整形(2)
document.querySelector('#result').src = "data:" + input.type
+ ";base64," + btoa(String.fromCharCode.apply(String, bytes));
} , true);
reader.readAsBinaryString(input);
}
}, true);
});
</script>
readAsBinaryStringメソッドは、生のバイナリデータを取得しますので、サンプルではこれをバイト配列に変換した上で(1)、更にこれを文字列変換し、最終的に、btoaメソッドでBase64エンコードしています(2)。これは、バイナリデータからバイト文字列を得る定型的な流れです。Base64エンコードできてしまえば、あとは「data:[コンテンツタイプ][;base64],データ本体」の構文に従って、Data URLを組み立てるだけです。
サンプルを見てもわかるように、取得したデータをそのまま、
TIPS 057:ファイル読み込みに失敗した場合の処理を定義する
FileReaderオブジェクトにerrorイベントリスナーを登録しておくことで、ファイルの読み込みに失敗した場合に、エラーメッセージの表示などのエラー処理を行えます。
[リスト05]読み込みエラー時にエラーメッセージを表示(readError.html)
<script>
window.addEventListener('DOMContentLoaded', function() {
// ファイルが指定されたタイミングで、その内容を表示
document.querySelector("#file").addEventListener('change', function(e) {
// File APIを利用できるかをチェック
if (window.File) {
// 指定されたファイルを取得
var input = document.querySelector('#file').files[0];
var reader = new FileReader();
reader.readAsDataURL(input);
reader.addEventListener('load', function(e) {
document.querySelector('#result').src = reader.result;
}, true);
// 読み込みエラー時の処理
reader.addEventListener('error', function(e) {
// エラーコードに対応するメッセージを準備(1)
var errors = [
'',
'指定のファイルが見つかりません。',
'読み込み権限がありません。',
'処理が中断されました。',
'読み込み中にエラーが発生しました。',
'ファイルサイズが大きすぎます。'
];
// エラーコードに応じてメッセージを表示(2)
document.querySelector('#err').innerHTML = errors[reader.error.code];
}, true);
}
}, true);
});
</script>
errorイベントリスナーの中では、error.codeプロパティでエラーコードにアクセスできます。エラーコードの意味は、以下のとおりです。
表4:error.codeプロパティの値
| エラーコード | 概要 |
|---|---|
| 1 | 指定のファイルが存在しない |
| 2 | 権限エラー(読み取り権限を持たないなど) |
| 3 | ファイルの読み込みを中断された |
| 4 | 読み込み中のエラー |
| 5 | ファイルサイズが許容上限を超えた |
サンプルでは、エラーコード1~5に対応するエラーメッセージを配列errorsにセットしておくことで(1)、codeプロパティの値に応じてメッセージを返しているわけです(2)。例えばエラーコード1で、erros[1]が取り出されます。
TIPS 058:ファイル読み込み時の進捗状況を表示する
読み込みの状況を追跡するには、progressイベントを利用します。progressイベントは、ファイル読み込みの開始から終了までの間、連続して発生するイベントです。
以下では、このprogressイベントを利用して、ファイルの読み込み状況を「●○%読み込み済み」のように、テキストで表示します。
[サンプル]読み込み率をテキスト表示するコード(readProgress.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>HTML5 TIPS</title>
<script>
window.addEventListener('DOMContentLoaded', function() {
// ファイルが指定されたタイミングで、その内容を表示
document.querySelector("#file").addEventListener('change', function(e) {
// 指定されたファイルを取得
if (window.File) {
// 指定されたファイルを取得
var input = document.querySelector('#file').files[0];
// ファイル読み込みの準備
var reader = new FileReader();
// ファイルの読み込みに成功したら、その内容を<img id="result">に反映
reader.addEventListener('load', function(e) {
document.querySelector('#result').src = reader.result;
}, true);
// ファイルの読み込み中に進捗状況を表示
reader.addEventListener('progress', function(e) {
// 「ロード済みサイズ÷総サイズ」で読み込み率を求める
document.querySelector('#prog').innerHTML =
Math.floor(e.loaded /e.total * 100);
}, true);
// ファイルの内容をData URL形式で取得
reader.readAsDataURL(input);
}
}, true);
});
</script>
</head>
<body>
ファイル:
<input id="file" name="file" type="file" />
<hr />
<span id="prog" style="color:Blue;">0</span>%読み込み済み
<img id="result" />
</body>
</html>
progressイベントリスナーの中では、totalプロパティでファイルの総サイズを、loadedプロパティで読み込み済みのサイズを、それぞれ取得できます。そこでサンプルでは、「loaded ÷ totaled × 100」という式で、読み込み済みのサイズ割合を求めています。progressイベントは、ファイルの読み込み中に連続して発生しますので、サンプルのようなリスナーを設けておくことで、読み込み割合が徐々に増えていく効果を実装しています。
JavaScriptでローカルファイルを自在に操る - File API
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- デスクトップアプリライクな操作性を実現するドラッグ&ドロップAPI
- プラグインは要らない!音声/動画対応したHTML5- / 要素
- スマホアプリ開発にも便利な位置情報API- Geolocation API-
- HTML5のドラッグ&ドロップAPI、File API、Web Storage
- クッキーより便利になったブラウザ標準ストレージ- Web Storage
- HTML+JavaScriptだけでブラウザに図形描画- Canvas API-
- 「TAURI」で「丸アートお絵描き」アプリを作ろう
- HTML+JavaScriptだけでブラウザに図形描画(3)- Canvas API-
- サンプルのプログラムコード解説
- HTML+JavaScriptだけでブラウザに図形描画(2)- Canvas API-


