FileReaderの機能
FileReaderとは、名前の通りファイルを読み込むためのAPIで、以下のメソッドを利用できます。
- readAsArrayBuffer(file)・・・ファイルを読み取った結果をArrayBuffer(型付き配列)の形式で保持します。
- readAsBinaryString(file)・・・ファイルを読み取った結果をString型で保持します。ファイルから読み取った内容(バイト配列)を、Stringのインターフェースを通じてアクセス可能にしているだけなので、結果をテキストとして扱うことはできません。
- readAsText(file, encode)・・・テキストファイルを読み取った結果をString型で保持します。ファイルの文字コードを指定することができます。
- readAsDataURL(file)・・・ファイルを読み取った結果をData URL形式の文字列で保持します。
- abort()・・・ファイルの読み込み処理を中断します。
このサンプルでは、テキストファイルを読み込む際に readAsText(file, encode)、画像ファイルを読み込む際にはreadAsDataURL(file) を利用しています。
FileReaderのreadAs...()メソッドは非同期で実行されます。実行結果はFileReader.resultというプロパティに各メソッドの形式でセットされます。
以下、テキストファイルを読み込む際のコードです。reader.result にはテキストファイル形式でデータがセットされます。
var reader = new FileReader(); reader.onload = function() { // reader.result にテキスト形式でデータでセットされている var result = reader.result; // 1行ずつ読み上げる } reader.readAsText(file, 'UTF-8');
次は、画像ファイルの読み込みです。
var reader = new FileReader(); reader.onload = function() { var result = reader.result; // 画像の色を解析をして虹を表示後、canvas上に表示する } reader.readAsText(file, encode);
記述の仕方自体は同じですが、reader.resultにセットされるファイル形式が[Data URL]になります。そのため、 tmpImg.src = reader.result のように受け渡すことができるようになり、画像の加工やcanvasへの反映を実現可能にしています。
var reader = new FileReader(); reader.onload = function() { var result = reader.result; // 画像の色を解析をして虹を表示後、canvas上に表示する var tmpImg = document.createElement('img'); tmpImg.src = reader.result; tmpImg.onload = function() { // 読み込んだ画像を加工して、canvas上に表示する var drawCanvas = $('#pict'); var canvasWidth = drawCanvas.attr('width'), canvasHeight = drawCanvas.attr('height'); var canvasProp = calcCanvasPosition(tmpImg.naturalWidth, tmpImg.naturalHeight, canvasWidth, canvasHeight); var pictCtx = drawCanvas[0].getContext('2d'); pictCtx.clearRect(0, 0, canvasWidth, canvasHeight); ・・・ } } reader.readAsDataURL(file);
window.URL.createObjectURL(file)
FileReader.readAsDataURL()は対象データを全てメモリ上に保持するため、メディアファイルのようにファイルサイズが大きいものには向いていません。ファイルの内容を全てメモリに読み込むことなく、ローカルのメディアデータをvideo要素やaudio要素、img要素を使用して処理するには、URL.createObjectURL()というメソッドが役に立ちます。
URL.createObjectURL()は、引数として渡されたファイルに対する参照を表すURL文字列を生成するメソッドです(実際はファイルに限らず、Blobと呼ばれるオブジェクトの全てに対してこのメソッドを呼び出すことができます)。
生成されるURLは、Blob URIという形式に則り、「blob:」で始まる短い文字列となります。
下記のコードは音楽ファイルの再生箇所の抜粋です。
function processAudioFile(file) { var audio = $('#audioPlayer')[0]; var audioData = URL.createObjectURL(file); // 音楽ファイルURLのセット audio.src = audioData; // 音楽再生 audio.play(); }
動画ファイルも同様に扱えます。こちらは再生ボタン・停止ボタンのイベントを登録しています。
function processVideoFile(file) { var tv = $('#tv'); var videoData = URL.createObjectURL(file); // 動画ファイルURLのセット tv.attr('src', videoData).show(); pauseFunc = function() { tv[0].pause(); }; // リモコンの再生ボタンで動画再生 $('#moviePlay').on('click', function(){ tv[0].play(); }); // リモコンの停止ボタンで動画停止 $('#movieStop').on('click', function(){ pauseFunc(); }); // 動画終了時 tv.on('ended', function(){ pauseFunc(); }); }
まとめ
File APIにより、「JavaScriptでファイルの内容を読み取る」というこれまで不可能とされてきた事柄を容易に実現できるようになりました。この一点だけでも、Webアプリケーションでの大きなイノベーションの予感を感じさせるAPIだといっても過言ではないでしょう。
また、冒頭でもお伝えしましたが、今後はローカルファイルへの書き出しやファイルシステムの取り扱いも視野に入れて仕様が検討されています。これらのAPIが実装された暁には、デスクトップアプリケーションと比べても機能的に全く劣ることがないような、さらに高度なWebアプリケーションの実現が期待できると言って良いでしょう。