JavaScriptFileReaderAPIを使用してファイルを読み取って処理する方法
序章
サポートするWebブラウザ FileReader と[1]ユーザーがファイルをアップロードできるようにします。
この記事では、File
、FileReader
、およびFileReaderSync
APIについて説明します。
前提条件
この記事をフォローしたい場合は、次のものが必要になります。
- JavaScriptのメソッド、 EventListener 、およびPromisesを理解しておくと役立ちます。
- コードエディタ。
File
、FileReader
、およびFileReaderSync
をサポートする最新のWebブラウザー。
ファイルのアップロード
まず、ユーザーからファイルを取得するには、<input>
要素を使用する必要があります。
<input id="input" type="file" />
このコードにより、ユーザーは自分のマシンからファイルをアップロードできます。
HTML<form>
を使用してファイルをアップロードする例を次に示します。
<form enctype="multipart/form-data" action="/upload" method="post"> <input id="input" type="file" /> </form>
アップロードの処理をより細かく制御するために、HTML<form>
の代わりにJavaScriptを使用してファイルを送信できます。
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()
は、blobのデータをバイナリ形式で含むArrayBuffer
を返します。.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>
Webブラウザでfile-blob-example.html
を開き、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が返されます。このURLは、Base64でエンコードされており、サーバーに送信する準備ができています。
readAsDataURL()
を使用する新しいfilereader-example.html
ファイルを作成します。
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>
Webブラウザでfilereader-example.html
を開き、myFile.txt
ファイルをinput
に追加します。 ファイルが処理されると、プログレスバーが画面に表示されます。 正常に読み込まれると、'Start Loading'
、'Loaded'
、および'Finished Loading'
と表示されます。
FileReaderSync
を使用する
FileReader
は、ファイルの読み取り中にメインスレッドをブロックしたくないため、非同期APIです。 たとえば、ブラウザが非常に大きなファイルを読み取ろうとしているときに、ユーザーインターフェイスが機能しなくなることは望ましくありません。 ただし、FileReaderSync
と呼ばれるFileReader
の同期バージョンがあります。 FileReaderSync
はWebワーカーでのみ使用できます。 Webワーカーには独自のスレッドがあるため、メインスレッドをブロックすることはありません。 FileReaderSync
はFileReader
と同じ方法を使用します。
FileReaderSync.readAsArrayBuffer()
FileReaderSync.readAsBinaryString()
FileReaderSync.readAsText()
FileReaderSync.readAsDataURL()
同期しているため、イベントハンドラーはありません。
結論
この記事では、File
、FileReader
、およびFileReaderSync
APIについて説明しました。
時間をかけてこれらの機能のブラウザサポートをチェックし、プロジェクトのユーザーに適用できることを確認してください。
追加のWebAPIで学習を続けてください。