コードの解説。
jQueryのイベントオブジェクトからファイルデータにアクセスするためのおまじない。
jQuery.event.props.push('dataTransfer');
PCからファイルがドロップされたときの処理
$("#file").bind("drop", function(event){ // ドロップされたファイルは、eventのdataTransferプロパティの // fileプロパティに配列(例によってArrayではない)に格納されている viewFileContent(event.dataTransfer.file[0]); }
ファイルの中身を読み取る処理
function viewFileContent(file) { // ファイル読み込みオブジェクトが実装されているかどうか? if (!window.FileReader) { console.log("ご利用のブラウザはファイル読み込みをサポートしていません") return; } var fr = new FileReader(); // バイナリ読み込みメソッドが実装されているかどうか? if (!fr.readAsArrayBuffer) { console.log("ご利用のブラウザはバイナリ読み込みをサポートしていません") return; } // ファイル読み込み時のイベントを設定 fr.onload = function(event){ // ファイルのデータが入ったArrayBufferオブジェクトを取得 var data = event.target.result; // Uint8Arrayは、ArrayBufferのデータに符号あり16ビット整数としてアクセスするためのラッパー // 普通に配列のようにアクセスできるが、 // 例によってJavaScriptのArrayオブジェクトではないので注意 var buf = new Uint8Array(data); // read console.log(buf[0]); console.log(buf[1]); // write buf[0] = 2; buf[1] = 16; // あとは好きなように処理すべし。重そうならWebWorkerに任せよう }; // ファイル読み込みエラー時の処理(read権限のないファイルとか) fr.onerror = function(error) { console.log(error); }; // ファイルデータへのアクセス開始。ArrayBufferオブジェクトとしてデータを取得する。 fr.readAsArrayBuffer(file); }
ファイル読み込みも、JavaScriptではおなじみのイベント駆動型の処理で行う。
ArrayBufferView
Uint8Arrayという謎のオブジェクトは、ArrayBufferのデータを操作するために用意されたArrayBufferViewのひとつ。Uint8Arrayを用いると、ArrayBufferのデータを8ビット符号なし整数として読み書きできる。
ArrayBufferViewには以下のオブジェクトがある。
- Int8Array
- Uint8Array
- Int16Array
- Uint16Array
- Int32Array
- Uint32Array
- Float32Array
- Float64Array
16、32、64ではバイトオーダがCPUネイティブになる(Intel CPUならリトルエンディアン)らしいので、Webで使うのは難しいかもしれない。
DataView
DataViewでは、インデックス指定アクセスはできないが、バイトオーダや符号を指定してデータを読み出すメソッドが用意されている。
var dataView = new DataView(data); // オフセット0からリトルエンディアンで、16ビットを符号なしの数値として取得 dataView.getUint16(0, true); // オフセット0からリトルエンディアンで、16ビットを符号ありの数値として取得 dataView.getInt16(0, true); // オフセット0からビッグエンディアンで、16ビットを符号なしの数値として取得 p(buf3.getUint16(0)); // オフセット0からビッグエンディアンで、16ビットを符号ありの数値として取得 p(buf3.getInt16(0));
ArrayBufferViewやDataViewは、ArrayBufferの参照を保持しているだけのビューなので、writeするとラップしているArrayBufferが書き換えられる。