TOP > カテゴリ > JavaScript >

ファイルを同期・非同期で読み込む[FileReaderSync/FileReader]

JavaScriptでファイルを「同期、非同期」で読む込む方法です。同期はスクリプトの実行と共に連続してファイルを読み込みます。非同期はスクリプトの実行とは別で一連のイベントが完了後にファイルを読み込みます。

※この記事の同期とは「連続してファイルを読み込む事」を同期としています。

この記事はバイナリ用です。
Image.onloadを同期で読み込む
Promiseを使用して複数のファイルを連続して読み込む[IE対応版]
も併せて読むと良いかも知れません。

非同期でファイルを読み込む

非同期でファイルを読み込むには「FileReader」オブジェクトを使用します。FileReader.readAsArrayBuffer()でファイルを読み込み、読み込みが成功した場合にFileReader.onload()のイベントが発生します。

<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">  

window.onload = function(){           
  var obj = document.getElementById("inputfile");  
  obj.addEventListener("change",onAddFile,false);
}

// ユーザーによりファイルが追加された  
function onAddFile(event) {
  var file   = event.target.files;       
  var reader = new FileReader();
  
  reader.onload = function (ev) {

    // ファイルの中身を取得  
    var Stream = new Uint8Array(reader.result);            
          
    // ... (ここに処理を追加する)

    // ファイルサイズを表示
    alert(Stream.length + 'バイト');
           
  };
  reader.readAsArrayBuffer(file[0]);          
}    
</script>
</head>
<body>
<form>
  <input type="file" id="inputfile">
</form>
</body>
</html>

ファイルを読み込んで、ファイルサイズをアラートで表示しています。

連続してファイルを読み込む(同期もどき)

連続してファイルを読み込むには「FileReaderSync」オブジェクトを使用します。このFileReaderSyncオブジェクトはWorkerオブジェクトで実行する必要があります。また、Workerオブジェクトは基本的に別ファイルで定義します。

[fileworkers.js]

// ファイルを読み込む
onmessage = function (event) {
  var reader = new FileReaderSync();
  var raw = reader.readAsArrayBuffer(event.data.file);

  postMessage({"raw": raw, "name": event.data.file.name });
};

[HTML]

<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">  
var worker = new Worker('fileworkers.js'); 

window.onload = function(){           
  var obj = document.getElementById("inputfile");  
  obj.addEventListener("change",onAddFile,false);
}

// ユーザーによりファイルが追加された  
function onAddFile(event) {
  var files = event.target.files; 
  
  document.getElementById("lst_file").innerHTML = ''; 

  // ワーカー経由でファイルを読み込む
  for (var i = 0; i < files.length; i++) {                 
    worker.postMessage({ "file": files[i]});
  }      
} 

// Workerからのメッセージ
worker.onmessage = function (event) {
  
  // ファイルの中身を取得
  //var Stream = new Uint8Array(event.data.raw);            

  // ... (ここに処理を追加する)

  // ファイル名をリストに表示する
  document.getElementById("lst_file").innerHTML = 
    document.getElementById("lst_file").innerHTML + event.data.name + '\n';            
}
</script>
</head>
<body>
<form>
  <input type="file" id="inputfile" multiple><br>
  <textarea id="lst_file" rows="10" cols="40" style="width:576px;" readonly></textarea>
</form>
</body>
</html>

このサンプルでは複数のファイルを連続して読み取ってファイル名を出力しています。実際はUint8Arrayのバイナリ配列から内容を読み取る処理を適宜、追加します。

Chromeの注意事項

ご使用のブラウザがChromeの場合はローカルで実行すると「Workerオブジェクト」のセキュリティエラーが発生します。

xxx.html:8 Uncaught SecurityError: Failed to construct 'Worker': Script at 'file:///C:/Users/xxx/Desktop/fileworkers.js' cannot be accessed from origin 'null'.

このエラーはChromeのセキュリティ対策の仕様です。尚、Webサーバー経由で実行するとエラーは出ません。

ローカル環境でエラーを表示させないようにするには「Web Workerに画像データを値渡しではなく参照渡しする」の事前準備をご覧ください。

対応ブラウザ

IE11/EdgeとChrome、FireFoxで確認しました。





関連記事



公開日:2015年12月28日 最終更新日:2016年05月24日
記事NO:01665