File System Access API でファイルの読み込み/書き込み

2021年11月23日火曜日

javascript

t f B! P L

enter image description here

File System Access API を使うと、ブラウザ上の JavaScirpt から、ユーザーのデバイス上のファイルやフォルダーへの読み書きができる。

似たものとして、File API がありますが、File System Access API と File API は別物です。

スポンサーリンク

すべてはハンドルを介して

デバイスのファイルを操作することから、当然、File System Access API は不正アクセスを防ぐセキュリティー上の考慮がされている。

File System Access API では、ファイルやディレクトリに対する操作はすべてハンドルを介して行います。このハンドルは、ユーザーのデバイス上にあるファイルやディレクトリを指し、ハンドルを取得するには、ユーザーが明示的にピッカーから対象を選択する必要がある。

ハンドルを取得するためのピッカーには、次の3つの種類(関数)がある。

  • window.showOpenFilePicker()
  • window.showSaveFilePicker()
  • window.showDirectoryPicker()

以降、これらのピッカーを使って、ファイル・ディレクトリへの操作を行う方法を解説する。

ローカルファイルを読み込む

最初は、ローカルファイルの読み取りを行うサンプルを作る。

以下は、ファイルを選択する為のボタンがクリックされると、window.showOpenFilePicker() でファイル選択ピッカーを表示し、ユーザーが選択したファイルのハンドルからデータを読み込み、コンソールに出力するサンプルコードである。

document.getElementById("open").addEventListener("click", async (e) => {
  [fileHandle] = await window.showOpenFilePicker();
  const file = await fileHandle.getFile();
  const fileContents = await file.text();
  console.log(fileContents);
};

ローカルファイルに書き込む

次に書き込み処理を行うサンプルを作る。File System Access API では、書き込み用のハンドルを取得して、デバイス上のファイルに直接データを書き込むことが可能。

以下は、window.showSaveFilePicker() でファイルの保存先を指定するピッカーを表示し、指定された保存先に対する書き込み用のハンドルを取得し、そこにテキストデータを書き込むサンプルコードである。

まず、ファイル保存先とファイルを選択するピッカーを表示する関数を作成する。window.showSaveFilePicker の戻り値は Promise であり、ユーザーが保存先を決定すると応答が返る為ため await にする。

//保存先選択ピッカーの表示
async function getNewFileHandle() {
  const options = {
    types: [
      {
        accept: {
          'text/plain': ['.txt'],
        },
      },
    ],
  };
  const handle = await window.showSaveFilePicker(options);
  return handle;
}

次に、ピッカーから受け取ったハンドルを使って、指定されたファイルにデータを書き込む処理を作成する。

ファイルへの書き込みには FileSystemWritableFileStream を基本的に使用する。このクラスへのインスタンは受け取ったハンドルの createWritable() から取得する。同じ名前のファイルが既に存在している場合は上書きされる。

document.getElementById("start").addEventListener("click", async (e) =>  {
  //保存先を選択するピッカーを表示する
  const fileHandle = await getNewFileHandle();
  //ファイルへ書き込むための FileSystemWritableFileStream を作成
  const writable = await fileHandle.createWritable();
  //テキストデータの書き込み
  await writable.write("書き込みデータ");
  //ファイルを閉じる
  await writable.close();
});

スポンサーリンク

ディレクトリ内のファイルを列挙

File System Access API では、ディレクトリに対するアクセスも可能である。

ディレクトリに対する操作は、次のようなことができる。

  • ディレクトリ内のファイルの列挙
  • ファイルの作成・削除
  • サブディレクトリの作成・削除

以下は、window.showDirectoryPicker() でユーザーが選択したディレクトリ内にあるファイルを列挙するサンプルコードである。

document.getElementById("open_folder").addEventListener("click", async (e) =>  {
  const dirHandle = await window.showDirectoryPicker();
  for await (const entry of dirHandle.values()) {
    console.log(entry.kind, entry.name);
  }
});

上のコードを実行すると、ディレクトリに対するアクセス権を求めるダイアログが表示され、ユーザーが許可しない限り、ピッカーで選択したディレクトリにアクセスできないようにセキュリティの制御がかかる。

enter image description here

スポンサーリンク

ブラウザのサポート状況

以下は、2021年11月時点のブラウザサポートの状況である。File System Access API は、Chrome 系のブラウザのみサポートが進んでおり、他のブラウザではまだ使えない。

enter image description here


しかし、ブラウザシャアで見れば、Chrome と Eage だけで全体の7割を超えるため、対応しているブラウザの種類は少ないが、実質は 7割程度のユーザーをカバーしているとも言える。

さいごに

File System Access API で、デバイス上のファイルやディレクトリに対する操作を行う方法を解説してきました。

File System Access API は比較的新しい API であり、まだ実装が行われていないブラウザもある。また、セキュリティ上の懸念もあることから、突如、これまで使えていたブラウザでも使用できなくなることが想定されるため、本番環境で使用する時は、File API などで代替する運用も検討しておいた方がよいであろう。

参考
https://web.dev/file-system-access/

スポンサーリンク

QooQ