LoginSignup
2
5

More than 5 years have passed since last update.

Web WorkersでFile API(FileReader)は使える

Posted at

ServiceW〇rkerではないです。Web Workersです。

概要

ふとFileが指定されたときに、Fileを使った処理をWorker側で処理が出来るかどうかを試した。

一応、Edge, Chromeで動いた。

Fileの内容によっては、負荷のかかる処理で止まることが考えられるので、それをごまかせる。

Demo

CSVファイルを読み取り、有効な件数を表示するもの

(複数ファイルが使えるPlaygroundって他にないかなぁ)

code

demoが見れなくなった時用

index.html
<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8" />
    <title>Hello worker</title>
  </head>

  <body>
    <input type="file" id="input_file">
    <div id="message">(ここにメッセージが入ります)</div>
    <script>
      window.addEventListener('load', function(){
        var file_el = document.getElementById('input_file');
        var message_el = document.getElementById('message');

        var worker = new Worker('worker.js');

        // workerの結果を受け取る
        worker.addEventListener('message', function(e){
          console.log('[Main]', e);
          message_el.textContent = e.data.message;
        });

        // ファイル選択時
        file_el.addEventListener('change', function(e){
          message_el.textContent = "処理中...";
          var file = file_el.files[0]
          console.log(file);
          // ファイルをWorkerへ渡す
          worker.postMessage(file);
        })
      })

    </script>
  </body>

</html>
worker.js
// CSVっぽいファイルデータを受け取り、適当に行数を数えるWorker
// 1行目 or カンマが2個未満はカウントしない
onmessage = function(e) {
  var file = e.data;
  if(!file){
    postMessage({message: 'データないっぽい'});
    return;
  }

  if(file.type != 'application/vnd.ms-excel'){
    postMessage({message: 'CSVファイルではないっぽい'});
    return;
  }

  var reader = new FileReader();

  // ファイル読み込み完了時
  reader.addEventListener('load', function(){
      /** @type String[] */
      var data = reader.result.split(/\r?\n/);
      reader.result = undefined; // 読み取り済みなので破棄。(意味ある?)

      // テキストとして読めている
      // console.log("data", data) 

      // 行数を数える
      var count = data.filter(function(s, idx){
        // 50MB,20万行でも一瞬で終わるので無意味処理で時間を稼ぐ
        for(var i=0; i<1000; ++i){
          s.replace(',');
        }
        return !(idx === 0 || s.replace(',').length < 2);
      }).length;

      // console.log("件数: "+ count);

      postMessage({message: "件数: "+ count});
      console.log('[Worker]', 'done');
  });

  // ファイルファイル読み込み
  reader.readAsText(e.data);
}
2
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5