2020年4月9日

ファイルとFileReader

FileオブジェクトはBlobを継承し、ファイルシステム関連の機能が拡張されています。

取得方法は2通りあります。

まず、Blobと同様のコンストラクタがあります。

new File(fileParts, fileName, [options])
  • fileParts – Blob/BufferSource/String値の配列です。
  • fileName – ファイル名文字列。
  • options – オプションオブジェクト。
    • lastModified – 最終変更のタイムスタンプ(整数日付)。

次に、より頻繁に使用される方法は、<input type="file">やドラッグアンドドロップ、その他のブラウザインターフェースからファイルを取得することです。この場合、ファイルはOSからこの情報を受け取ります。

FileBlobを継承しているので、Fileオブジェクトは同じプロパティに加えて、以下のプロパティを持ちます。

  • name – ファイル名。
  • lastModified – 最終変更のタイムスタンプ。

このようにして、<input type="file">からFileオブジェクトを取得できます。

<input type="file" onchange="showFile(this)">

<script>
function showFile(input) {
  let file = input.files[0];

  alert(`File name: ${file.name}`); // e.g my.png
  alert(`Last modified: ${file.lastModified}`); // e.g 1552830408824
}
</script>
ご注意ください

input要素は複数のファイルを選択できるので、input.filesはそれらを格納した配列のようなオブジェクトです。ここではファイルが1つしかないので、input.files[0]を取得しています。

FileReader

FileReaderは、Blob(したがってFileも)オブジェクトからデータを読み取ることを唯一の目的とするオブジェクトです。

ディスクからの読み込みには時間がかかる可能性があるため、イベントを使用してデータを提供します。

コンストラクタ

let reader = new FileReader(); // no arguments

主なメソッド

  • readAsArrayBuffer(blob) – バイナリ形式のArrayBufferでデータを読み取ります。
  • readAsText(blob, [encoding]) – 指定されたエンコーディング(デフォルトはutf-8)でデータをテキスト文字列として読み取ります。
  • readAsDataURL(blob) – バイナリデータを読み取り、base64データURLとしてエンコードします。
  • abort() – 操作をキャンセルします。

どのread*メソッドを選択するかは、好ましい形式とデータの使用方法によって異なります。

  • readAsArrayBuffer – バイナリファイルの場合、低レベルのバイナリ操作を行うために使用します。スライスなどの高レベル操作の場合は、FileBlobを継承しているので、読み取る必要がなく直接呼び出すことができます。
  • readAsText – テキストファイルの場合、文字列を取得したいときに使用します。
  • readAsDataURL – このデータimgタグなどのsrc属性で使用したい場合に使用します。第Blob章で説明したように、これにはファイルを読み取る代替手段があります:URL.createObjectURL(file)

読み込みが進むと、以下のイベントが発生します。

  • loadstart – 読み込み開始。
  • progress – 読み込み中。
  • load – エラーなし、読み込み完了。
  • abortabort()が呼び出された。
  • error – エラーが発生した。
  • loadend – 成功または失敗に関わらず、読み込み終了。

読み込みが完了すると、結果は次のようにアクセスできます。

  • reader.resultは結果(成功した場合)。
  • reader.errorはエラー(失敗した場合)。

最も広く使用されているイベントは、間違いなくloaderrorです。

ファイルを読み取る例を次に示します。

<input type="file" onchange="readFile(this)">

<script>
function readFile(input) {
  let file = input.files[0];

  let reader = new FileReader();

  reader.readAsText(file);

  reader.onload = function() {
    console.log(reader.result);
  };

  reader.onerror = function() {
    console.log(reader.error);
  };

}
</script>
BlobのためのFileReader

Blob章で説明したように、FileReaderはファイルだけでなく、任意のBlobを読み取ることができます。

これを使用して、Blobを別の形式に変換できます。

  • readAsArrayBuffer(blob)ArrayBufferへ。
  • readAsText(blob, [encoding]) – 文字列へ(TextDecoderの代替)。
  • readAsDataURL(blob) – base64データURLへ。
FileReaderSyncはWeb Worker内で使用できます。

Web Workerには、FileReaderの同期バリアントであるFileReaderSyncも存在します。

その読み込みメソッドread*はイベントを生成せず、通常の関数のように結果を返します。

これはWeb Worker内でのみ有効です。なぜなら、ファイルからの読み取り中に発生する可能性のある同期呼び出しの遅延は、Web Workerではそれほど重要ではないからです。ページに影響を与えません。

まとめ

FileオブジェクトはBlobを継承します。

Blobのメソッドとプロパティに加えて、FileオブジェクトはnamelastModifiedプロパティを持ち、ファイルシステムから読み取る内部機能も備えています。通常、<input>やドラッグアンドドロップイベント(ondragend)など、ユーザー入力からFileオブジェクトを取得します。

FileReaderオブジェクトは、3つの形式のいずれかでファイルまたはBlobを読み取ることができます。

  • 文字列(readAsText)。
  • ArrayBufferreadAsArrayBuffer)。
  • データURL、base-64エンコード(readAsDataURL)。

しかし、多くの場合、ファイルの内容を読み取る必要はありません。Blobで行ったように、URL.createObjectURL(file)を使用して短いURLを作成し、それを<a>または<img>に割り当てることができます。このようにして、ファイルはダウンロードしたり、キャンバスの一部として画像として表示したりすることができます。

また、ネットワークを介してFileを送信する場合も簡単です。XMLHttpRequestfetchなどのネットワークAPIは、Fileオブジェクトをネイティブに受け入れます。

チュートリアルマップ

コメント

コメントする前にこれを読んでください…
  • 改善点の提案がある場合は、コメントする代わりにGitHub issueまたはプルリクエストを送信してください。
  • 記事の内容が理解できない場合は、詳しく説明してください。
  • いくつかのコードを挿入するには<code>タグを使用し、複数行の場合は<pre>タグで囲み、10行を超える場合はサンドボックス(plnkrjsbincodepen…)を使用してください。