Skip to content
概要 ブログ 学習する 探検 パターン Case studies
このページ内
  • 最新の File System Access API
  • 従来のやり方でファイルを操作する方法
  • ファイルを選択
    • HTML入力要素
    • カスタムドラッグアンドドロップ
    • ディレクトリの場合は?
  • ファイルメタデータの読み取り
  • ファイルのコンテンツを読み取る
    • 読み取られたファイルの進捗を監視する
  • Home
  • All articles

JavaScriptでファイルを読む

ファイルを選択し、ファイルのメタデータとコンテンツを読み取り、読み取りの進捗を監視する方法。

Jun 18, 2010 — 更新済み Mar 29, 2021
Available in: English、Español、Português、Русский、中文、한국어
Kayce Basques
Kayce Basques
TwitterGitHubGlitchHomepage
Pete LePage
Pete LePage
TwitterGitHubGlitchHomepage
Thomas Steiner
Thomas Steiner
TwitterGitHubGlitchHomepage
このページ内
  • 最新の File System Access API
  • 従来のやり方でファイルを操作する方法
  • ファイルを選択
    • HTML入力要素
    • カスタムドラッグアンドドロップ
    • ディレクトリの場合は?
  • ファイルメタデータの読み取り
  • ファイルのコンテンツを読み取る
    • 読み取られたファイルの進捗を監視する

ユーザーのローカルデバイスにあるファイルを選択して操作することは、Webで最も一般的に使用される機能の1つです。これにより、ユーザーはファイルを選択し、サーバーにアップロードすることができます。たとえば、写真をアップロードしたり、税務書類の提出したりできます。ただし、サイトは、ネットワーク経由でデータを転送せずにファイルを読み取り、操作するということもできてしまいます。

最新の File System Access API #

File System Access API (ファイルシステムアクセス) API は、ユーザーのローカルシステム上のファイルとディレクトリの読み取りおよび書き込みの両方を簡単に行う方法を提供します。現在、ChromeやEdgeなど、ほとんどのChromium派生ブラウザで利用できます。詳細については、File System Access API の記事を参照してください。

File System Access API は、まだすべてのブラウザーと互換性があるわけではないため、利用可能な場合に新しいAPIを使用するヘルパーライブラリ、browser-fs-access、をご確認ください。新しいAPIが利用可能でない場合は、従来のアプローチにフォールバックします。

従来のやり方でファイルを操作する方法 #

このガイドでは、以下を行う方法について説明します。

  • ファイルを選択
    • HTML入力要素の使用
    • drag-and-dropゾーンの使用
  • ファイルのメタデータを読み取る
  • ファイルの中身を読む

ファイルを選択 #

HTML入力要素 #

ユーザーがファイルを選択できるようにする最も簡単な方法は、すべての主要なブラウザーでサポートされている<input type="file">要素を使用することです。クリックすると、ユーザーはオペレーティングシステムの組み込みファイル選択UIを使用して、単一のファイル、またはmultiple属性が含まれている場合は、複数のファイルを選択できます。ユーザーが1つまたは複数のファイルの選択を終了すると、要素のchangeイベントが発生します。ファイルの一覧は、FileListオブジェクトであるevent.target.filesからアクセスできます。FileListの各アイテムは、Fileオブジェクトです。

<!-- The `multiple` attribute lets users select multiple files. -->
<input type="file" id="file-selector" multiple>
<script>
const fileSelector = document.getElementById('file-selector');
fileSelector.addEventListener('change', (event) => {
const fileList = event.target.files;
console.log(fileList);
});
</script>
window.showOpenFilePicker()メソッドは、ファイルハンドルを使用して、ファイルを読み取るだけでなく、ファイルへの書き戻しもできるため、自分のユースケースにおいて実行可能な代替手段であるかどうかを確認します。 この方法はポリフィルすることができます。

この例では、ユーザーはオペレーティングシステムの組み込みファイル選択UIを使用して複数のファイルを選択し、選択した各ファイルをコンソールに記録できます。

ユーザーが選択できるファイルの種類を制限する #

場合によっては、ユーザーが選択できるファイルの種類を制限したいときがあります。たとえば、画像編集アプリが、テキストファイルではなく、画像のみを受け入れるようにする場合です。これを行うには、入力要素にaccept属性を追加して、受け入れるファイルを指定します。

<input type="file" id="file-selector" accept=".jpg, .jpeg, .png">

カスタムドラッグアンドドロップ #

一部のブラウザでは、<input type="file">要素もドロップターゲットであるため、ユーザーはアプリにファイルをドラッグアンドドロップできます。ただし、ドロップターゲットは小さいため、使いにくい場合があります。代わりに、<input type="file">要素を使ってコア機能を指定したら、大きなカスタムドラッグアンドドロップサーフェスを提供できます。

DataTransferItem.getAsFileSystemHandle()メソッドは、ファイルハンドルも提供し、ファイルの読み取りだけでなく、ファイルへの書き戻しもできるため、ユースケースの実行可能な代替手段であるかどうかを確認してください。

ドロップゾーンを選択する #

ドロップサーフェスは、アプリケーションの設計によって異なります。ドロップサーフェスは、ウィンドウの一部のみ、またはウィンドウ全体にすることもできます。

画像圧縮WebアプリSquooshのスクリーンショット。
Squooshは、ウィンドウ全体をドロップゾーンにします。

Squooshを使用すると、ユーザーは画像をウィンドウ内の任意の場所にドラッグアンドドロップでき、画像を選択を選択すると、<input type="file">要素が呼び出されます。何をドロップゾーンとする場合も、そのサーフェスにファイルをドラッグアンドドロップできることをユーザーが分かるようにしましょう。

ドロップゾーンを定義する #

要素をドラッグアンドドロップゾーンにするには、2 つのイベント dragover と drop をリッスンする必要があります。dragoverイベントは、ブラウザのUIを更新して、ドラッグアンドドロップアクションがファイルのコピーを作成していることを視覚的に示します。drop イベントは、ユーザーがファイルをサーフェスにドロップした後に発生します。入力要素の場合と同じように、ファイルの一覧は、FileList オブジェクトである event.dataTransfer.files からアクセスできます。FileListの各アイテムは、File オブジェクトです。

const dropArea = document.getElementById('drop-area');

dropArea.addEventListener('dragover', (event) => {
event.stopPropagation();
event.preventDefault();
// Style the drag-and-drop as a "copy file" operation.
event.dataTransfer.dropEffect = 'copy';
});

dropArea.addEventListener('drop', (event) => {
event.stopPropagation();
event.preventDefault();
const fileList = event.dataTransfer.files;
console.log(fileList);
});

event.stopPropagation()およびevent.preventDefault()は、ブラウザーのデフォルトの動作が実行されないようにし、代わりにコードが実行されるようにします。これらのメソッドがないと、ブラウザはページから離れ、ユーザーがブラウザウィンドウにドロップしたファイルを開きます。

{#この例は埋め込みとしては機能しません。#}

ライブデモンストレーションは、Custom drag-and-drop (カスタムドラッグアンドドロップ)をご覧ください。

ディレクトリの場合は? #

残念ながら、現時点では、ディレクトリにアクセスする良い方法はありません。

<input type="file"> 要素の webkitdirectory 属性を使用すると、単一のディレクトリまたは複数のディレクトリを選択できます。一部のChromiumベースのブラウザのほか、おそらくデスクトップ版のSafari でもサポートされていますが、ブラウザの互換性について矛盾した情報が報告されています。

window.showDirectoryPicker()メソッドは、ファイルハンドルも提供し、ファイルの読み取りだけでなく、ファイルへの書き戻しもできるため、ユースケースの実行可能な代替手段であるかどうかを確認してください。この方法はポリフィルすることができます。

ドラッグアンドドロップが有効になっていると、ユーザーはディレクトリをドロップゾーンにドラッグしようとするかもしれません。ドロップイベントが発生すると、ディレクトリの File オブジェクトが含まれますが、ディレクトリ内のファイルには一切アクセスできなくなります。

ファイルメタデータの読み取り #

Fileオブジェクトには、ファイルに関するいくつかのメタデータプロパティが含まれています。ほとんどのブラウザは、ファイル名、ファイルのサイズ、およびMIMEタイプを提供しますが、プラットフォームによっては、ブラウザが提供する情報が違ったり、他のブラウザよりも多くの情報が提供されたりする場合があります。

function getMetadataForFileList(fileList) {
for (const file of fileList) {
// Not supported in Safari for iOS.
const name = file.name ? file.name : 'NOT SUPPORTED';
// Not supported in Firefox for Android or Opera for Android.
const type = file.type ? file.type : 'NOT SUPPORTED';
// Unknown cross-browser support.
const size = file.size ? file.size : 'NOT SUPPORTED';
console.log({file, name, type, size});
}
}

実際の動作は、input-type-file Glitch デモでご覧いただけます。

ファイルのコンテンツを読み取る #

ファイルを読み取るには、 FileReaderを使用します。これにより、Fileオブジェクトのコンテンツをメモリに読み込むことができます。 FileReaderには、ファイルを配列バッファー、データURL 、またはテキストとして読み取るように指示できます。

function readImage(file) {
// Check if the file is an image.
if (file.type && !file.type.startsWith('image/')) {
console.log('File is not an image.', file.type, file);
return;
}

const reader = new FileReader();
reader.addEventListener('load', (event) => {
img.src = event.target.result;
});
reader.readAsDataURL(file);
}

上記の例では、ユーザーが指定した File を読み取り、それをデータ URL に変換し、そのデータ URL を使って img 要素に画像を表示しています。ユーザーが画像ファイルを選択したことを確認する方法は、read-image-file をご覧ください。

読み取られたファイルの進捗を監視する #

大きなファイルを読み取るときは、読み取りがどこまで進んだかを示すUXを提供すると便利な場合があります。そうするには、FileReader が提供する progress イベントを使用します。progress イベントは、loaded (読み取られた量) と total (読み取る量の合計) という 2 つのプロパティを提供します。

function readFile(file) {
const reader = new FileReader();
reader.addEventListener('load', (event) => {
const result = event.target.result;
// Do something with result
});

reader.addEventListener('progress', (event) => {
if (event.loaded && event.total) {
const percent = (event.loaded / event.total) * 100;
console.log(`Progress: ${Math.round(percent)}`);
}
});
reader.readAsDataURL(file);
}

ヒーロー画像、Unsplash、Vincent Botta 氏提供

ストレージ
最終更新: Mar 29, 2021 — 記事を改善する
Return to all articles
共有する
サブスクライブする

Contribute

  • バグを報告する
  • ソースを表示する

関連性のあるコンテンツ

  • developer.chrome.com
  • Chrome のアップデート
  • ケーススタディ
  • ポッドキャスト
  • ショー

接続する

  • Twitter
  • YouTube
  • Google Developers
  • Chrome
  • Firebase
  • Google Cloud Platform
  • すべての製品
  • 利用規約とプライバシーポリシー
  • コミュニティガイドライン

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies.