Blob と File クラスについて
・ | Blob と File クラスについて |
・ | Blob オブジェクトを作成する |
・ | File オブジェクトを作成する |
・ | File オブジェクトを取得する |
・ | File クラスのプロパティについて |
・ | File クラスのメソッドについて |
・ | 大容量のデータを制御する |
Blob と File クラスについて
■File クラスについて
File クラスは、HTML5 世代の機能です。
http://www.w3.org/TR/FileAPI/ (Working Draft)
■File クラスについて
File オブジェクトは、特定の1つのファイルと紐付けされています。
該当するファイルに、実際に読み取りアクセスできる権限が与えられています。
■Blob クラスについて
Blob クラスは、File クラスの原型となるクラスです。
Blob オブジェクトは、特定のファイルへのアクセス権限はありません。
Blob オブジェクトは、「コンテンツタイプ情報」と「バッファ情報」の2つを内包する事ができます。
1つの仮想的なファイル(小塊)として取り扱う事ができます。
■ File インターフェースの派生について
Blob |
↓派生 |
File |
■ブラウザが File クラスをサポートしているか調べる
window.File が真であるか比較します。
InternetExplorer 9 以前では、対応していません。
■ローカルファイルの中身に読み取りアクセスする
Blob や File クラスには、読み取りアクセスする機能が存在しません。
別途、FileReader クラスを使用します。
■ローカルファイルをリソースとして活用する
Blob URL Scheme を使用します。
例えば、ローカルにある画像ファイルを、<IMG> 要素に表示する事ができます。
Blob オブジェクトを作成する
■ Blob オブジェクトを作成する
■ Blob オブジェクトを作成する
new 演算子を使って、Blob オブジェクトを作成します。
Internet Explorer 9 以前では、対応していません。
Safari 5 以前では、対応していません。
new Blob ( [バッファデータ] , {オプション} ) :Blob
第01引数(略可) | Array | バッファデータを配列に格納して指定する。複数のデータを指定すると、内部で昇順に結合され1つのバッファとなる。 |
第02引数(略可) | BlobPropertyBag | Blob クラスのプロパティ値を設定する。(size 以外) |
戻り値 | Blob | Blob オブジェクトが得られる。 |
■第01引数(バッファデータ)
バッファデータを、配列に格納して指定します。
複数のデータを格納すると、内部で昇順に結合されます。
配列に格納できるデータ形式は、以下の通りです。
型 | 備考 |
ArrayBuffer | 内部で保有するバッファ全体。 |
TypedArray | 内部で保有するバッファのうち、アクセス可能な範囲内のみ。 |
Blob | 内部で保有するバッファ全体。 |
String | UTF-8 形式のバイナリに変換される。(第02引数で別の文字セットを指定しても必ず、UTF-8 形式となるので注意) |
その他 | 文字列型に変換される。 |
■第02引数(BlobPropertyBag オブジェクト)
新規にオブジェクトを作成し、以下のプロパティを追加します。
type プロパティは、Blob URL Scheme を生成する際に重要です。
プロパティ名 | 型 | 説明 |
type | String | コンテンツタイプを指定する。 |
■作成例
Blob オブジェクトを作成(中身が空)
// ------------------------------------------------------------
// Blob オブジェクトを作成(中身が空)
// ------------------------------------------------------------
var blob = new Blob();
// 出力テスト
console.log(blob);
console.log("type:" + (blob.type)); // ""
console.log("size:" + (blob.size)); // 0
Blob オブジェクトを作成(UTF-8 形式のプレーンテキスト)
// ------------------------------------------------------------
// 適当なバッファを用意
// ------------------------------------------------------------
var str = "文字列テスト";
var source = [ str ];
// ------------------------------------------------------------
// BlobPropertyBag オブジェクトを用意
// ------------------------------------------------------------
var blob_property_bag = {
type: "text/plain"
};
// ------------------------------------------------------------
// Blob オブジェクトを作成(UTF-8 形式のプレーンテキスト)
// ------------------------------------------------------------
var blob = new Blob( source , blob_property_bag );
// 出力テスト
console.log("type:" + (blob.type)); // "text/plain"
console.log("size:" + (blob.size)); // 18
// ------------------------------------------------------------
// FileReader オブジェクトを生成
// ------------------------------------------------------------
var file_reader = new FileReader();
// ------------------------------------------------------------
// 読み込み完了時に実行されるイベント(成功失敗に関係なく)
// ------------------------------------------------------------
file_reader.onloadend = function(e){
// エラー
if(file_reader.error) return;
// 出力テスト
console.log(file_reader.result); // "文字列テスト"
};
// ------------------------------------------------------------
// 読み込みを開始する(テキスト文字列を得る)
// ------------------------------------------------------------
file_reader.readAsText(blob);
Blob オブジェクトを作成(バイナリ形式)
// ------------------------------------------------------------
// 適当なバッファを用意
// ------------------------------------------------------------
var ary_u8 = new Uint8Array([0x00,0x01,0x02,0x03]);
var source = [ ary_u8 ];
// ------------------------------------------------------------
// BlobPropertyBag オブジェクトを用意
// ------------------------------------------------------------
var blob_property_bag = {
type: "application/octet-stream"
};
// ------------------------------------------------------------
// Blob オブジェクトを作成(バイナリ形式)
// ------------------------------------------------------------
var blob = new Blob( source , blob_property_bag );
// 出力テスト
console.log("type:" + (blob.type)); // "application/octet-stream"
console.log("size:" + (blob.size)); // 4
// ------------------------------------------------------------
// FileReader オブジェクトを生成
// ------------------------------------------------------------
var file_reader = new FileReader();
// ------------------------------------------------------------
// 読み込み完了時に実行されるイベント(成功失敗に関係なく)
// ------------------------------------------------------------
file_reader.onloadend = function(e){
// エラー
if(file_reader.error) return;
// Uint8Array オブジェクトを作成する
var ary_u8 = new Uint8Array(file_reader.result);
// 出力テスト
console.log(ary_u8); // [0x00,0x01,0x02,0x03]
};
// ------------------------------------------------------------
// 読み込みを開始する(ArrayBuffer オブジェクトを得る)
// ------------------------------------------------------------
file_reader.readAsArrayBuffer(blob);
複数のバッファを結合しつつ、Blob オブジェクトを作成(バイナリ形式)
// ------------------------------------------------------------
// 複数の適当なバッファを用意
// ------------------------------------------------------------
var ary_u8_a = new Uint8Array([0x00,0x01,0x02,0x03]);
var ary_u8_b = new Uint8Array([0x04,0x05,0x06]);
var ary_u8_c = new Uint8Array([0x07,0x08]);
var source = [ ary_u8_a , ary_u8_b , ary_u8_c ];
// ------------------------------------------------------------
// BlobPropertyBag オブジェクトを用意
// ------------------------------------------------------------
var blob_property_bag = {
type: "application/octet-stream"
};
// ------------------------------------------------------------
// Blob オブジェクトを作成(バイナリ形式)
// ------------------------------------------------------------
var blob = new Blob( source , blob_property_bag );
// 出力テスト
console.log("type:" + (blob.type)); // "application/octet-stream"
console.log("size:" + (blob.size)); // 9
// ------------------------------------------------------------
// FileReader オブジェクトを生成
// ------------------------------------------------------------
var file_reader = new FileReader();
// ------------------------------------------------------------
// 読み込み完了時に実行されるイベント(成功失敗に関係なく)
// ------------------------------------------------------------
file_reader.onloadend = function(e){
// エラー
if(file_reader.error) return;
// Uint8Array オブジェクトを作成する
var ary_u8 = new Uint8Array(file_reader.result);
// 出力テスト
console.log(ary_u8); // [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08]
};
// ------------------------------------------------------------
// 読み込みを開始する(ArrayBuffer オブジェクトを得る)
// ------------------------------------------------------------
file_reader.readAsArrayBuffer(blob);
File オブジェクトを作成する
■ File オブジェクトの作成について
■ File オブジェクトの作成について
任意のバッファをソースにして、File オブジェクトを作成できます。
この場合、ローカルファイルとは、何の関係もありません。
一時的な仮想ファイルとして機能するでしょう。
■ローカルファイルにアクセスするには?
File オブジェクトは作成しません。
UI を経由して、File オブジェクトを取得します。
■ File オブジェクトを作成する
■ File オブジェクトを作成する
new 演算子を使って、File オブジェクトを作成します。
new File ( [バッファデータ] , "ファイル名" , {オプション} ) :File
第01引数 | Array | バッファデータを配列に格納して指定する。複数のデータを指定すると、内部で昇順に結合され1つのバッファとなる。 |
第02引数 | String | ファイル名を指定する。(name と同等) |
第03引数(略可) | FilePropertyBag | File クラスのプロパティ値を設定する。(name と size 以外) |
戻り値 | File | File オブジェクトが得られる。 |
■第01引数(バッファデータ)
Blob コンストラクタの第01引数と同等です。
■第03引数(FilePropertyBag オブジェクト)
新規にオブジェクトを作成し、以下のプロパティを追加します。
プロパティ名 | 型 | 説明 |
type | String | コンテンツタイプを設定する。 |
lastModified | Number | 最終更新日時を設定する(単位:ミリ秒) |
■作成例
File オブジェクトを作成(UTF-8 形式のプレーンテキスト)
// ------------------------------------------------------------
// 適当なバッファを用意
// ------------------------------------------------------------
var str = "文字列テスト";
var source = [ str ];
// ------------------------------------------------------------
// FilePropertyBag オブジェクトを用意
// ------------------------------------------------------------
var file_property_bag = {
// コンテンツタイプを設定
type: "text/plain",
// 最終更新日時を設定(単位:ミリ秒)
lastModified: 0
};
// ------------------------------------------------------------
// File オブジェクトを作成(UTF-8 形式のプレーンテキスト)
// ------------------------------------------------------------
var file = new File( source , "test.txt" , file_property_bag );
// 出力テスト
console.log("name:" + (file.name)); // "test.txt"
console.log("type:" + (file.type)); // "text/plain"
console.log("size:" + (file.size)); // 18
// ------------------------------------------------------------
// FileReader オブジェクトを生成
// ------------------------------------------------------------
var file_reader = new FileReader();
// ------------------------------------------------------------
// 読み込み完了時に実行されるイベント(成功失敗に関係なく)
// ------------------------------------------------------------
file_reader.onloadend = function(e){
// エラー
if(file_reader.error) return;
// 出力テスト
console.log(file_reader.result); // "文字列テスト"
};
// ------------------------------------------------------------
// 読み込みを開始する(テキスト文字列を得る)
// ------------------------------------------------------------
file_reader.readAsText(file);
File オブジェクトを作成(バイナリ形式)
// ------------------------------------------------------------
// 適当なバッファを用意
// ------------------------------------------------------------
var ary_u8 = new Uint8Array([0x00,0x01,0x02,0x03]);
var source = [ ary_u8 ];
// ------------------------------------------------------------
// FilePropertyBag オブジェクトを用意
// ------------------------------------------------------------
var file_property_bag = {
// コンテンツタイプを設定
type: "application/octet-stream",
// 最終更新日時を設定(単位:ミリ秒)
lastModified: 0
};
// ------------------------------------------------------------
// File オブジェクトを作成(バイナリ形式)
// ------------------------------------------------------------
var file = new File( source , "text.dat" , file_property_bag );
// 出力テスト
console.log("name:" + (file.name)); // "test.dat"
console.log("type:" + (file.type)); // "application/octet-stream"
console.log("size:" + (file.size)); // 4
// ------------------------------------------------------------
// FileReader オブジェクトを生成
// ------------------------------------------------------------
var file_reader = new FileReader();
// ------------------------------------------------------------
// 読み込み完了時に実行されるイベント(成功失敗に関係なく)
// ------------------------------------------------------------
file_reader.onloadend = function(e){
// エラー
if(file_reader.error) return;
// Uint8Array オブジェクトを作成する
var ary_u8 = new Uint8Array(file_reader.result);
// 出力テスト
console.log(ary_u8); // [0x00,0x01,0x02,0x03]
};
// ------------------------------------------------------------
// 読み込みを開始する(ArrayBuffer オブジェクトを得る)
// ------------------------------------------------------------
file_reader.readAsArrayBuffer(file);
複数のバッファを結合しつつ、File オブジェクトを作成(バイナリ形式)
// ------------------------------------------------------------
// 複数の適当なバッファを用意
// ------------------------------------------------------------
var ary_u8_a = new Uint8Array([0x00,0x01,0x02,0x03]);
var ary_u8_b = new Uint8Array([0x04,0x05,0x06]);
var ary_u8_c = new Uint8Array([0x07,0x08]);
var source = [ ary_u8_a , ary_u8_b , ary_u8_c ];
// ------------------------------------------------------------
// FilePropertyBag オブジェクトを用意
// ------------------------------------------------------------
var file_property_bag = {
// コンテンツタイプを設定
type: "application/octet-stream",
// 最終更新日時を設定(単位:ミリ秒)
lastModified: 0
};
// ------------------------------------------------------------
// File オブジェクトを作成(バイナリ形式)
// ------------------------------------------------------------
var file = new File( source , "test.dat" , file_property_bag );
// 出力テスト
console.log("name:" + (file.name)); // "test.dat"
console.log("type:" + (file.type)); // "application/octet-stream"
console.log("size:" + (file.size)); // 9
// ------------------------------------------------------------
// FileReader オブジェクトを生成
// ------------------------------------------------------------
var file_reader = new FileReader();
// ------------------------------------------------------------
// 読み込み完了時に実行されるイベント(成功失敗に関係なく)
// ------------------------------------------------------------
file_reader.onloadend = function(e){
// エラー
if(file_reader.error) return;
// Uint8Array オブジェクトを作成する
var ary_u8 = new Uint8Array(file_reader.result);
// 出力テスト
console.log(ary_u8); // [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08]
};
// ------------------------------------------------------------
// 読み込みを開始する(ArrayBuffer オブジェクトを得る)
// ------------------------------------------------------------
file_reader.readAsArrayBuffer(file);
File オブジェクトを取得する
■ File オブジェクトの取得について
■セキュリティについて
ユーザーに知られる事なく、ローカルファイルにアクセスする事はできません。
ユーザーによるファイルの選択(許可)が必要です。
■ローカルファイルを取得できる UI について
■ File オブジェクトを取得する
■ファイル選択コントロールについて
<input type="file"> 要素 の、files プロパティを使用します。
■ドラッグアンドドロップについて
DataTransfer クラスの、files プロパティを使用します。
ファイルリストを取得する例は、こちらです。
■クリップボードについて
DataTransfer クラスの、files プロパティを使用します。
ファイルリストを取得する例は、こちらです。
File クラスのプロパティについて
■ファイルのプロパティ一覧
■ Blob インターフェース
プロパティ名 | 型 | 説明 |
size | Number | バイトサイズを取得する |
type | String | コンテンツタイプを取得する |
■ File インターフェース
プロパティ名 | 型 | 説明 |
name | String | ファイル名を取得する |
lastModified | Number | 最終更新日時を取得する(単位:ミリ秒) |
lastModifiedDate | Date | 最終更新日時を取得する |
File クラスのメソッドについて
■バッファの開始と終了位置を指定して、新しい Blob オブジェクトを生成する
slice() メソッドを使用します。
第02引数で指定する終了位置は、取得対象に含まれません。
Blob.slice( 開始位置 , 終了位置 , "コンテンツタイプ" ) :Blob
第01引数(略可) | Number | 開始位置を指定。(0 から始まる番号)デフォルトは 0 |
第02引数(略可) | Number | 終了位置を指定。(0 から始まる番号)デフォルトはすべての要素 マイナス値を指定すると「length + 第02引数」 の位置。(-1で最後尾は含まれない) |
第03引数(略可) | String | 新しい Blob オブジェクトのコンテンツタイプを指定する。省略した場合、空文字となる。 |
戻り値 | Blob | 新しい Blob オブジェクトが得られる。 |
■ Blob オブジェクトの複製について
引数を省略した場合、バッファ全体の複製となります。
この場合、コンテンツタイプは空文字となるので注意して下さい。
■使用例
Blob オブジェクトを複製する
// ------------------------------------------------------------
// Blob オブジェクトを複製する関数
// ------------------------------------------------------------
function BlobClone(blob){
return blob.slice(0 , blob.size , blob.type);
}
// ------------------------------------------------------------
// 適当なバッファを用意
// ------------------------------------------------------------
var ary_u8 = new Uint8Array([0x00,0x01,0x02,0x03]);
var source = [ ary_u8 ];
// ------------------------------------------------------------
// BlobPropertyBag オブジェクトを用意
// ------------------------------------------------------------
var blob_property_bag = {
type: "application/octet-stream"
};
// ------------------------------------------------------------
// Blob オブジェクトを作成(バイナリ形式)
// ------------------------------------------------------------
var blob_a = new Blob( source , blob_property_bag );
// ------------------------------------------------------------
// Blob オブジェクトを複製
// ------------------------------------------------------------
var blob_b = BlobClone(blob_a);
// 出力テスト
console.log("type:" + (blob_b.type)); // "application/octet-stream"
console.log("size:" + (blob_b.size)); // 4
// ------------------------------------------------------------
// FileReader オブジェクトを生成
// ------------------------------------------------------------
var file_reader = new FileReader();
// ------------------------------------------------------------
// 読み込み完了時に実行されるイベント(成功失敗に関係なく)
// ------------------------------------------------------------
file_reader.onloadend = function(e){
// エラー
if(file_reader.error) return;
// Uint8Array オブジェクトを作成する
var ary_u8 = new Uint8Array(file_reader.result);
// 出力テスト
console.log(ary_u8); // [0x00,0x01,0x02,0x03]
};
// ------------------------------------------------------------
// 読み込みを開始する(ArrayBuffer オブジェクトを得る)
// ------------------------------------------------------------
file_reader.readAsArrayBuffer(blob_b);
開始と終了位置を指定して、新しい Blob オブジェクトを作成する
// ------------------------------------------------------------
// 適当なバッファを用意
// ------------------------------------------------------------
var str = "あいうえお";
var source = [ str ];
// ------------------------------------------------------------
// BlobPropertyBag オブジェクトを用意
// ------------------------------------------------------------
var blob_property_bag = {
type: "text/plain"
};
// ------------------------------------------------------------
// Blob オブジェクトを作成(UTF-8 形式のプレーンテキスト)
// ------------------------------------------------------------
var blob_a = new Blob( source , blob_property_bag );
// ------------------------------------------------------------
// 開始と終了位置を指定して、新しい Blob オブジェクトを作成
// ------------------------------------------------------------
var blob_b = blob_a.slice(3 , 9);
// ------------------------------------------------------------
// FileReader オブジェクトを生成
// ------------------------------------------------------------
var file_reader = new FileReader();
// ------------------------------------------------------------
// 読み込み完了時に実行されるイベント(成功失敗に関係なく)
// ------------------------------------------------------------
file_reader.onloadend = function(e){
// エラー
if(file_reader.error) return;
// Uint8Array オブジェクトを作成する
var ary_u8 = new Uint8Array(file_reader.result);
// 出力テスト
console.log(ary_u8); // [ 0xE3,0x81,0x84 , 0xE3,0x81,0x86 ] (い,う)
};
// ------------------------------------------------------------
// 読み込みを開始する(ArrayBuffer オブジェクトを得る)
// ------------------------------------------------------------
file_reader.readAsArrayBuffer(blob_b);
大容量のデータを制御する
■大容量のデータを作成する(複数の ArrayBuffer の連結)
ArrayBuffer クラスの弱点
ArrayBuffer は、物理メモリの確保を試みる性質上、
一度に 1Gbyte といった巨大なサイズを指定すると、失敗する可能性が高くなります。
メモリの利用状況や断片化状況などによって大きく左右されます。
ブラウザごとに設定されているサイズ上限もあります。
Chrome では 2046Mbyte まで (ver.109の時点) (0x7FE00000)
Firefox では 8192Mbyte まで (ver.109の時点) (0x200000000)
例えば以下のコードは、一度に 10GByte の ArrayBuffer オブジェクトの作成を試みますが、必ず失敗するでしょう。
大容量の ArrayBuffer オブジェクトの作成を試みる(大きすぎるので失敗する)
// 初期サイズを指定して、ArrayBuffer オブジェクトを作成する
var ary_buffer = new ArrayBuffer(10*1024*1024*1024);
// 出力テスト
console.log(ary_buffer);
console.log(ary_buffer.byteLength);
Blob クラスで解決する
そこで Blob クラスを使用します。
Blob クラスは、小さなバッファ同士を仮想的に連結することで、あたかも1つの巨大なデータであるかのように取り扱うことができます。
複数のバッファを結合するには、 Blob コンストラクタを使用します。
ArrayBuffer クラスは、物理メモリと密接に連動する性質上、大容量を扱うことができません。
その為1つに連結して巨大なバッファを生成するような機能が用意されていません。(代わりに Blob クラスを使用します)
作成例
10GByte の Blob オブジェクトの作成する例です。
ArrayBuffer オブジェクトを 100Mbyte ずつ確保して、それらを順番に連結させます。
物理メモリが大量に積まれている実行環境であれば、成功するでしょう。
少しずつバッファを連結して、大容量の Blob オブジェクトを作成する
// ------------------------------------------------------------
// 空の Blob オブジェクトを作成
// ------------------------------------------------------------
var blob = new Blob();
// ------------------------------------------------------------
// 100 回繰り返す
// ------------------------------------------------------------
var i = 0;
var num = 100;
for(i=0;i < num;i++){
// 初期サイズを指定して、ArrayBuffer オブジェクトを作成する
var ary_buffer = new ArrayBuffer(100 * 1024 * 1024);
// Blob 型にラッピングする
var blob_sub = new Blob([ary_buffer]);
// 最後尾に連結する
blob = new Blob([blob , blob_sub]);
}
// ------------------------------------------------------------
// 出力テスト
// ------------------------------------------------------------
console.log(blob);
console.log(blob.size); // 10485760000
Out Of Memory エラーを回避する
第01引数は、ArrayBuffer 型や TypedArray 型の指定にも対応していますが、Out Of Memory エラーを引き起こしやすいです。
Blob 型に変換してから、Blob 型同士の連結を試みると、主要ブラウザで成功するようです。
Blob 型のリストを指定して、一発でまとめて連結する(成功しやすい)
// ------------------------------------------------------------
// 空の配列を用意
// ------------------------------------------------------------
var blob_list = new Array();
// ------------------------------------------------------------
// 100 回繰り返す
// ------------------------------------------------------------
var i = 0;
var num = 100;
for(i=0;i < num;i++){
// 初期サイズを指定して、ArrayBuffer オブジェクトを作成する
var ary_buffer = new ArrayBuffer(100 * 1024 * 1024);
// Blob 型にラッピングする
var blob = new Blob([ary_buffer]);
// 配列の最後尾に登録
blob_list.push(blob);
}
// ------------------------------------------------------------
// Blob オブジェクトを作成(一度にすべて連結する)
// ------------------------------------------------------------
var blob_large = new Blob(blob_list);
// ------------------------------------------------------------
// 出力テスト
// ------------------------------------------------------------
console.log(blob_large);
console.log(blob_large.size); // 10485760000
ArrayBuffer 型のリストを指定して、一発でまとめて連結する(失敗しやすいので非推奨)
// ------------------------------------------------------------
// 空の配列を用意
// ------------------------------------------------------------
var ary_buffer_list = new Array();
// ------------------------------------------------------------
// 100 回繰り返す
// ------------------------------------------------------------
var i = 0;
var num = 100;
for(i=0;i < num;i++){
// 初期サイズを指定して、ArrayBuffer オブジェクトを作成する
var ary_buffer = new ArrayBuffer(100 * 1024 * 1024);
// 配列の最後尾に登録
ary_buffer_list.push(ary_buffer);
}
// ------------------------------------------------------------
// Blob オブジェクトを作成(一度にすべて連結する)
// ------------------------------------------------------------
var blob_large = new Blob(ary_buffer_list);
// ------------------------------------------------------------
// 出力テスト
// ------------------------------------------------------------
console.log(blob_large);
console.log(blob_large.size); // 10485760000
■大容量のデータを少しずつ読み出す
Blob オブジェクトからデータを取り出すには?
FileReader クラスを使用します。
例えば、Blob オブジェクトの中身を ArrayBuffer 型で取り出すには、readAsArrayBuffer() メソッドを使用します。
読み取りメソッドの注意点
ここで注意したいのが、読み取りメソッドはサイズが大きすぎると、失敗する可能性があるということです。
例えば、10GByte の Blob オブジェクトから1回ですべてを読み取ろうとすると、内部で 10GByte の ArrayBuffer オブジェクトの作成が試みられるため、必ず失敗するでしょう。
読み取り区間を絞って解決する
そこで slice() メソッドを使用します。
100Mbyte といった無理のないサイズで、読み取り区間を絞ることができます。
そして読み取りメソッドを何度も呼び出す事で、少しずつアクセスします。
読み取り例
少しずつファイルを読み込む
<html>
<body>
<form>
<input type="file" id="aaa" >
</form>
<script type="text/javascript">
<!--
// "aaa" という ID 属性のエレメントを取得する
var input_file = document.getElementById("aaa");
// ------------------------------------------------------------
// 値が変化した時に実行されるイベント
// ------------------------------------------------------------
input_file.onchange = function (){
// ファイルが選択されたか
if(!(input_file.value)) return;
// ------------------------------------------------------------
// File オブジェクトを取得(HTML5 世代)
// ------------------------------------------------------------
// ファイルリストを取得
var file_list = input_file.files;
if(!file_list) return;
// 0 番目の File オブジェクトを取得
var file = file_list[0];
if(!file) return;
// ------------------------------------------------------------
// 読み取り設定
// ------------------------------------------------------------
// ファイル位置
var file_pos = 0;
// ファイルの総サイズ
var file_total = file.size;
// 一度に読み取るサイズ
var read_size = 100 * 1024 * 1024;
// ------------------------------------------------------------
// 繰り返し実行
// ------------------------------------------------------------
function readExec(){
// ------------------------------------------------------------
// FileReader オブジェクトを生成
// ------------------------------------------------------------
var file_reader = new FileReader();
// ------------------------------------------------------------
// 読み込みが成功したときに実行されるイベント
// ------------------------------------------------------------
file_reader.addEventListener("load",function(e){
// データの中身を取得
var array_buffer = file_reader.result;
var ary_u8 = new Uint8Array(array_buffer);
console.log("pos:(" + file_pos + "/" + file_total + ") size:" + array_buffer.byteLength);
console.log(ary_u8);
// ファイル位置を進める
file_pos += array_buffer.byteLength;
if(file_pos < file_total){
// 次の読み込みを開始
readExec();
}else{
console.log("最後まで読み込んだ");
}
});
// ------------------------------------------------------------
// 読み込みが失敗したときに実行されるイベント
// ------------------------------------------------------------
file_reader.addEventListener("error",function(e){
console.log("読み込みが失敗した");
// エラーオブジェクトを取得
console.log(file_reader.error);
});
// ------------------------------------------------------------
// 今回読み取る区間を切り出す
// ------------------------------------------------------------
var blob = file.slice(file_pos , file_pos+read_size);
// ------------------------------------------------------------
// 読み込みを開始する
// ------------------------------------------------------------
file_reader.readAsArrayBuffer(blob);
}
// 開始
readExec();
};
//-->
</script>
</body>
</html>
■大容量のデータをリソースとして活用する
Blob オブジェクトをリソースとして活用するには?
window.URL.createObjectURL() メソッドを使用します。
使用例
動的に生成した、10GByte のバイナリデータをダウンロードさせる例
<html>
<body>
<form>
<a id="aaa" >wait...</a>
</form>
<script type="text/javascript">
<!--
// ------------------------------------------------------------
// 10GByte 分のバッファを用意する(100Mbyte ずつ分割して作成)
// ------------------------------------------------------------
var ary_buffer_list = (function(){
var ary = new Array();
var i = 0;
var num = 100;
for(i=0;i < num;i++){
var ary_buffer = new ArrayBuffer(100 * 1024 * 1024);
ary.push(ary_buffer);
}
return ary;
})();
// ------------------------------------------------------------
// バッファをすべて連結して Blob オブジェクトを作成
// ------------------------------------------------------------
var blob = (function(){
var ary = new Array();
var i = 0;
var num = ary_buffer_list.length;
for(i=0;i < num;i++){
var ary_buffer = ary_buffer_list[i];
var blob = new Blob([ary_buffer]);
ary.push(blob);
}
var blob = new Blob(ary , {type:"application/octet-stream"} );
return blob;
})();
// ------------------------------------------------------------
// Blob URL Scheme を生成する
// ------------------------------------------------------------
var blob_url = window.URL.createObjectURL(blob);
// ------------------------------------------------------------
// "aaa" という ID 属性のエレメントを取得する
// ------------------------------------------------------------
var anchor_element = document.getElementById("aaa");
// ------------------------------------------------------------
// ダウンロードボタンに変更
// ------------------------------------------------------------
anchor_element.download = "sample.dat";
anchor_element.href = blob_url;
anchor_element.textContent = "クリックしてダウンロード";
//-->
</script>
</body>
</html>