序章

サポートするWebブラウザ FileReaderユーザーがファイルをアップロードできるようにします。

この記事では、 File, FileReader、 と FileReaderSync API。

前提条件

この記事をフォローしたい場合は、次のものが必要になります。

  • JavaScriptのメソッド EventListener 、およびPromisesを理解しておくと役立ちます。
  • コードエディタ。
  • サポートする最新のWebブラウザ File, FileReader、 と FileReaderSync.

ファイルのアップロード

まず、ユーザーからファイルを取得するには、 <input> エレメント:

<input id="input" type="file" />

このコードにより、ユーザーは自分のマシンからファイルをアップロードできます。

HTMLを使用してファイルをアップロードする例を次に示します。 <form>:

<form enctype="multipart/form-data" action="/upload" method="post">
  <input id="input" type="file" />
</form>

アップロードの処理をより細かく制御するために、HTMLの代わりにJavaScriptを使用できます <form> ファイルを送信するには:

let file = document.getElementById('input').files[0];
let formData = new FormData();

formData.append('file', file);
fetch('/upload/image', {method: "POST", body: formData});

このアプローチでは、FormDataおよびfetchを使用します。

使用する File Blob プロパティ

最新のブラウザでは、 Files 持ってる Blob プロパティと関数。 これらの関数を使用すると、ファイルを読み取ることができます。

  • .text() ファイルをストリームに変換してから文字列に変換します。
  • .stream() を返します ReadableStream.
  • .arrayBuffer() を返します ArrayBuffer これには、blobのデータがバイナリ形式で含まれています。
  • .slice() ファイルのスライスを取得できます。

新しいを作成します myFile.txt いくつかのテキストを含むファイル:

myFile.txt
Example file content.

次に、新しいを作成します file-blob-example.html ファイル:

file-blob-example.html
<!DOCTYPE html>
<html>
<body>
  <input type="file" id="input" />

  <script>
    const streamToText = async (blob) => {
      const readableStream = await blob.getReader();
      const chunk = await readableStream.read();

      return new TextDecoder('utf-8').decode(chunk.value);
    };

    const bufferToText = (buffer) => {
      const bufferByteLength = buffer.byteLength;
      const bufferUint8Array = new Uint8Array(buffer, 0, bufferByteLength);

      return new TextDecoder().decode(bufferUint8Array);
    };

    document.getElementById('input').addEventListener('change', function(e) {
      let file = document.getElementById('input').files[0];

      (async () => {
        const fileContent = await file.text();

        console.log('.text()', fileContent);

        const fileContentStream = await file.stream();

        console.log('.stream()', await streamToText(fileContentStream));

        const buffer = await file.arrayBuffer();

        console.log('.buffer()', bufferToText(buffer));

        const fileSliceBlob = file.slice(0, file.length);
        const fileSliceBlobStream = await fileSliceBlob.stream();

        console.log('.slice() and .stream()', await streamToText(fileSliceBlobStream));
      })();
    });
  </script>
</body>
</html>

開ける file-blob-example.html Webブラウザで追加します myFile.txt ファイルに input. Web開発者コンソールで、を使用して読み取られたファイルの内容が表示されます。 .text(), .stream(), .buffer()、 と .slice().

このアプローチでは、 ReadableStream TextDecoder()、および Uint8Array()を使用します。

申請中 FileReader ライフサイクルと方法

FileReaderには6つの主要なイベントが添付されています。

  • loadstart:ファイルのロードを開始すると発生します。
  • progress:blobがメモリに読み込まれたときに発生します。
  • abort:電話すると発火 .abort.
  • error:エラー発生時に発生します。
  • load:読み取りが成功したときに発生します。
  • loadend:ファイルがロードされ、エラーまたはアボートが呼び出されなかった場合、またはロードが新しい読み取りを開始した場合に発生します。

ファイルのロードを開始するには、次の4つの方法があります。

  • readAsArrayBuffer(file):ファイルまたはBLOBを配列バッファーとして読み取ります。 1つのユースケースは、大きなファイルをServiceWorkerに送信することです。
  • readAsBinaryString(file):ファイルをバイナリ文字列として読み取ります
  • readAsText(file, format):ファイルをUSVString(ほとんど文字列のように)として読み取り、オプションの形式を指定できます。
  • readAsDataURL(file):これにより、ファイルのコンテンツにアクセスできるURLが返されます。これは、Base64でエンコードされており、サーバーに送信する準備ができています。

新しいを作成します filereader-example.html を使用するファイル readAsDataURL():

filereader-example.html
<!DOCTYPE html>
<html>
<head>
  <style>
    body {
      background: #000;
      color: white;
    }

    #progress-bar {
      margin-top: 1em;
      width: 100vw;
      height: 1em;
      background: red;
      transition: 0.3s;
    }
  </style>
</head>
<body>
  <input type="file" id="input" />
  <progress value="0" max="100" id="progress-bar"></progress>
  <div id="status"></div>
  <script>
    const changeStatus = (status) => {
      document.getElementById('status').innerHTML = status;
    }

    const setProgress = (e) => {
      const fr = e.target;
      const loadingPercentage = 100 * e.loaded / e.total;

      document.getElementById('progress-bar').value = loadingPercentage;
    }

    const loaded = (e) => {
      const fr = e.target;
      var result = fr.result;

      changeStatus('Finished Loading!');
      console.log('Result:', result);
    }

    const errorHandler = (e) => {
      changeStatus('Error: ' + e.target.error.name);
    }

    const processFile = (file) => {
      const fr = new FileReader();

      fr.readAsDataURL(file);
      fr.addEventListener('loadstart', changeStatus('Start Loading'));
      fr.addEventListener('load', changeStatus('Loaded'));
      fr.addEventListener('loadend', loaded);
      fr.addEventListener('progress', setProgress);
      fr.addEventListener('error', errorHandler);
      fr.addEventListener('abort', changeStatus('Interrupted'));
    }

    document.getElementById('input').addEventListener('change', (e) => {
      const file = document.getElementById('input').files[0];

      if (file) {
        processFile(file);
      }
    });
  </script>
</body>
</html>

開ける filereader-example.html Webブラウザで追加します myFile.txt ファイルに input. ファイルが処理されると、プログレスバーが画面に表示されます。 正常に読み込まれると、 'Start Loading', 'Loaded'、 と 'Finished Loading'.

使用する FileReaderSync

FileReader ファイルの読み取り中にメインスレッドをブロックしたくないため、は非同期APIです。 たとえば、ブラウザが非常に大きなファイルを読み取ろうとしているときに、ユーザーインターフェイスが機能しなくなることは望ましくありません。 ただし、の同期バージョンがあります FileReader と呼ばれる FileReaderSync. しか使えない FileReaderSync Webワーカーで。 Webワーカーには独自のスレッドがあるため、メインスレッドをブロックすることはありません。 FileReaderSync と同じ方法を使用します FileReader:

  • FileReaderSync.readAsArrayBuffer()
  • FileReaderSync.readAsBinaryString()
  • FileReaderSync.readAsText()
  • FileReaderSync.readAsDataURL()

同期しているため、イベントハンドラーはありません。

結論

この記事では、 File, FileReader、 と FileReaderSync API。

時間をかけてこれらの機能のブラウザサポートをチェックし、プロジェクトのユーザーに適用できることを確認してください。

追加のWebAPIで学習を続けてください。