From b304be34b611766ba544d23717dfed8ed433ef1d Mon Sep 17 00:00:00 2001 From: Masahiro FUJIMOTO Date: Fri, 1 Dec 2023 21:37:49 +0900 Subject: [PATCH 1/4] =?UTF-8?q?2023/10/26=20=E6=99=82=E7=82=B9=E3=81=AE?= =?UTF-8?q?=E8=8B=B1=E8=AA=9E=E7=89=88=E3=81=AB=E5=9F=BA=E3=81=A5=E3=81=8D?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- files/ja/web/api/file_system_api/index.md | 61 +++++++++-------------- 1 file changed, 24 insertions(+), 37 deletions(-) diff --git a/files/ja/web/api/file_system_api/index.md b/files/ja/web/api/file_system_api/index.md index e6c61731091427..097bba830c50fd 100644 --- a/files/ja/web/api/file_system_api/index.md +++ b/files/ja/web/api/file_system_api/index.md @@ -1,15 +1,17 @@ --- -title: File System Access API +title: ファイルシステム API slug: Web/API/File_System_API +l10n: + sourceCommit: 835d6632d59993861a0458510402787f8a2c3cb3 --- -{{securecontext_header}}{{DefaultAPISidebar("File System Access API")}} +{{securecontext_header}}{{DefaultAPISidebar("File System API")}} -File System Access API により、ファイルの読み込み、書き込み、管理ができます。 +ファイルシステム API は - [ファイルシステムアクセス API](https://wicg.github.io/file-system-access/) を介して提供される拡張機能により - 端末のファイルシステム上のファイルにアクセスし、読み取り、書き込み、ファイル管理機能を使用することができます。 ## 概念と使用法 -この API を用いると、ユーザーのローカルデバイス上のファイルや、ユーザーがアクセス可能なネットワークファイルシステムを操作することができます。この API の基本機能として、ファイルの読み込み、ファイルの書き込み (保存)、ディレクトリー構造へのアクセスがあります。 +この API を用いると、ユーザーのローカルデバイス上のファイルや、ユーザーがアクセス可能なネットワークファイルシステムを操作することができます。この API の基本機能として、ファイルの読み込み、ファイルの書き込み(保存)、ディレクトリー構造へのアクセスがあります。 ファイルやディレクトリーの操作のほとんどは、ハンドルを介して行います。親クラスの {{domxref('FileSystemHandle')}} の補助により {{domxref('FileSystemFileHandle')}} および {{domxref('FileSystemDirectoryHandle')}} の 2 個の子クラスが定義されており、それぞれファイルおよびディレクトリーの操作に用います。 @@ -17,52 +19,36 @@ File System Access API により、ファイルの読み込み、書き込み、 以下の方法によりファイルハンドルへのアクセス権を得ることもできます。 -- {{domxref('HTML Drag and Drop API', 'HTML Drag and Drop API', '', 'nocode')}} の {{domxref('DataTransferItem.getAsFileSystemHandle()')}} メソッド -- [File Handling API](https://developer.chrome.com/en/articles/file-handling/) +- {{domxref('HTML Drag and Drop API', 'HTML ドラッグ&ドロップ API', '', 'nocode')}} の {{domxref('DataTransferItem.getAsFileSystemHandle()')}} メソッド +- [ファイルハンドリング API](https://developer.chrome.com/en/articles/file-handling/) -それぞれのハンドルが自身の機能を提供し、どっちを使っているかによって少し違いがあります。(詳細は、[インターフェイス](#%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%82%A4%E3%82%B9)の節を参照してください) ファイルのデータや、選択されたディレクトリーの情報 (子を含む) にアクセスできます。この API により、ウェブに欠けていた潜在的な機能への道が開きます。それでも、セキュリティは API の設計時に最大限考慮するべきことであり、ファイルやディレクトリーのデータへのアクセスはユーザーが特に許可しない限り禁止されています。 +それぞれのハンドルが自身の機能を提供し、どっちを使っているかによって少し違いがあります(詳細は、[インターフェイス](#%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%82%A4%E3%82%B9)の節を参照してください)。ファイルのデータや、選択されたディレクトリーの情報(子を含む)にアクセスできます。この API により、ウェブに欠けていた潜在的な機能への道が開きます。それでも、セキュリティは API の設計時に最大限考慮するべきことであり、ファイルやディレクトリーのデータへのアクセスはユーザーが特に許可しない限り禁止されています(これは、ユーザーから見えない[オリジンプライベートファイルシステム](#オリジンプライベートファイルシステム)の場合とは異なります)。 -> **メモ:** API の機能を使う際に投げられる可能性がある例外は、仕様書での定義に沿って関連するページに一覧が載っています。しかし、API と下層のオペレーティングシステムの相互作用により、状況はより複雑になります。[仕様書でエラーの対応関係を一覧にする](https://github.com/whatwg/fs/issues/57)ための提案がなされており、ここに有用な関連情報があります。 +> **メモ:** API の機能を使う際に投げられる可能性がある例外は、仕様書での定義に沿って関連するページに一覧が載っています。しかし、 API と下層のオペレーティングシステムの相互作用により、状況はより複雑になります。[仕様書でエラーの対応関係を一覧にする](https://github.com/whatwg/fs/issues/57)ための提案がなされており、ここに有用な関連情報があります。 > **メモ:** {{domxref("FileSystemHandle")}} をベースとするオブジェクトは、{{domxref("IndexedDB API", "IndexedDB", "", "nocode")}} のデータベースのインスタンスにシリアライズしたり、{{domxref("window.postMessage", "postMessage()")}} を介して転送したりできます。 ### オリジンプライベートファイルシステム -[オリジンプライベートファイルシステム (OPFS)](https://fs.spec.whatwg.org/#origin-private-file-system) は、ページのオリジン固有のストレージのエンドポイントであり、パフォーマンスに高度に最適化された特別な種類のファイルへのアクセスを選択可能です。例えば、ファイルの内容を in-place で排他的に書き換えることができます。 +オリジンプライベートファイルシステム (OPFS) は、ページのオリジン固有のストレージのエンドポイントであり、パフォーマンスに高度に最適化された特別な種類のファイルへのアクセスを選択可能です。例えば、ファイルの内容をその場 (in-place) で排他的に書き換えることができます。 -OPFS へのファイルの保存は、({{domxref("IndexedDB API", "IndexedDB API", "", "nocode")}} などの) ブラウザーが提供する他のページのオリジンに固有のデータを保存する仕組みに似ています。すなわち、OPFS 内のファイルは、ピッカーを用いて選択されたファイルとは以下の点で異なります。 - -- OPFS 内のファイルへのアクセスには、許可の要求は必要ありません。 -- サイトのデータを消去すると、OPFS も消去されます。 -- OPFS は、ブラウザーが使う容量の制限の対象になります。 - -OPFS 内のファイルは、以下の 3 ステップで操作できます。 - -1. (ワーカーやメインスレッドで [`navigator.storage.getDirectory()`](/ja/docs/Web/API/Navigator/storage) で得られる) {{domxref("StorageManager.getDirectory()")}} メソッドを呼び、ディレクトリーとその中身にアクセスするための {{domxref("FileSystemDirectoryHandle")}} オブジェクトへの参照を得ます。これは、OPFS のルートを表します。 -2. {{domxref("FileSystemDirectoryHandle.getFileHandle()")}} メソッドを呼び、ディレクトリ内の特定のファイルのハンドルを表す {{domxref('FileSystemFileHandle')}} オブジェクトを得ます。 -3. そのファイルハンドルで {{domxref('FileSystemFileHandle.createSyncAccessHandle', 'createSyncAccessHandle()')}} メソッドを呼び、ファイルの読み書きに利用できる {{domxref('FileSystemSyncAccessHandle')}} オブジェクトを得ます。これは、_同期式の_ 読み書き操作を行うための高効率なハンドルです。(他のハンドルの種類では非同期です) このクラスの同期式であるという性質は、([WebAssembly](/ja/docs/WebAssembly) などの) 非同期の操作が大きなオーバーヘッドに繋がる状況での使用を意図した、パフォーマンスの優位性をもたらします。なお、これはそれ用の [Web Workers](/ja/docs/Web/API/Web_Workers_API) 内でのみ使用可能です。 - -ブラウザーは通常 OPFS の内容をディスク上のどこかに保存して永続化することで実装しますが、これは内容にユーザーが簡単にアクセスできるようにすることを意図したものではありません。ブラウザーはファイルがあるように見せるかもしれない一方、データベースや他の任意のデータ構造に保存されているかも知れません。作成したファイルがハードディスク上のどこかに 1 対 1 対応で置かれていることを期待することはできません。 - -> **メモ:** {{domxref('FileSystemSyncAccessHandle.write()')}} による書き込みは in-place で行われます。すなわち、変更は writer に書き込まれると同時に実際の対応するファイルに書き込まれます。これは ({{domxref('FileSystemFileHandle.createWritable()')}} などの) この API で利用可能な書き込みのための他の仕組みでは成り立たず、書き込みストリームが閉じられるまで変更はディスクに書き込まれません。 +使い方の説明は、[オリジンプライベートファイルシステム](/ja/docs/Web/API/File_System_API/Origin_private_file_system)を読んでください。 ### ファイルの保存 -「保存」の機能があります。 - - 非同期ハンドルでは、{{domxref('FileSystemWritableFileStream')}} インターフェイスを使います。保存したいデータを {{domxref('Blob')}}、{{jsxref("String")}} オブエクト、文字列リテラル、{{jsxref('ArrayBuffer', 'buffer')}} のいずれかの形式にしたら、ストリームを開いてデータをファイルに保存できます。既存のファイルも新しいファイルも保存先にできます。 -- 同期式の {{domxref('FileSystemSyncAccessHandle')}} では、{{domxref('FileSystemSyncAccessHandle.write', 'write()')}} メソッドを用いて変更をファイルに書き込みます。特定のタイミングで変更をディスクに書き込みたい場合は、{{domxref('FileSystemSyncAccessHandle.flush', 'flush()')}} を呼ぶことができます。(これを呼ばない場合、下層のオペレーティングシステムに任せて都合のいいときに処理させることができ、ほとんどの場合はこれでいいでしょう) +- 同期的に {{domxref('FileSystemSyncAccessHandle')}} では、{{domxref('FileSystemSyncAccessHandle.write', 'write()')}} メソッドを用いて変更をファイルに書き込みます。特定のタイミングで変更をディスクに書き込みたい場合は、{{domxref('FileSystemSyncAccessHandle.flush', 'flush()')}} を呼ぶことができます。(これを呼ばない場合、下層のオペレーティングシステムに任せて都合のいいときに処理させることができ、ほとんどの場合はこれでいいでしょう) ## インターフェイス - {{domxref("FileSystemHandle")}} - - : **`FileSystemHandle`** インターフェイスは、エントリーを表すオブジェクトです。複数のハンドルが同じエントリーを表すことがあります。ほとんどの場面では、`FileSystemHandle` を直接扱うことはなく、子インターフェイスの {{domxref('FileSystemFileHandle')}} や {{domxref('FileSystemDirectoryHandle')}} を扱うことになるでしょう。 + - : **`FileSystemHandle`** インターフェイスは、項目を表すオブジェクトです。複数のハンドルが同じ項目を表すことがあります。ほとんどの場面では、`FileSystemHandle` を直接扱うことはなく、子インターフェイスの {{domxref('FileSystemFileHandle')}} や {{domxref('FileSystemDirectoryHandle')}} を扱うことになるでしょう。 - {{domxref("FileSystemFileHandle")}} - - : ファイルシステムのエントリーを表すハンドルを提供します。 + - : ファイルシステムの項目を表すハンドルを提供します。 - {{domxref("FileSystemDirectoryHandle")}} - : ファイルシステムのディレクトリーを表すハンドルを提供します。 - {{domxref("FileSystemSyncAccessHandle")}} - - : ディスク上の単一のファイルを in-place で操作する、ファイルシステムのエントリーへの同期式のハンドルを提供します。このファイルの読み書きを同期式で行える性質は、[WebAssembly](/ja/docs/WebAssembly) などの非同期操作が大きなオーバーヘッドに繋がる場面における重要なメソッドで処理効率を高めることを可能にします。このクラスは、それ用の [Web Workers](/ja/docs/Web/API/Web_Workers_API) 内で[オリジンプライベートファイルシステム](#%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%B3%E3%83%97%E3%83%A9%E3%82%A4%E3%83%99%E3%83%BC%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)内のファイルを扱う場合のみ使用可能です。 + - : ディスク上の単一のファイルをその場 (in-place) で操作する、ファイルシステムの項目への同期的にハンドルを提供します。このファイルの読み書きを同期的に行える性質は、[WebAssembly](/ja/docs/WebAssembly) などの非同期操作が大きなオーバーヘッドに繋がる場面における重要なメソッドで処理効率を高めることを可能にします。このクラスは、それ用の[ウェブワーカー](/ja/docs/Web/API/Web_Workers_API)内で[オリジンプライベートファイルシステム](#オリジンプライベートファイルシステム)内のファイルを扱う場合のみ使用可能です。 - {{domxref("FileSystemWritableFileStream")}} - : ディスク上の単一のファイルを操作する便利な関数が追加された {{domxref('WritableStream')}} です。 @@ -137,7 +123,7 @@ async function returnPathDirectories(directoryHandle) { // relativePaths は、相対パスを表す名前の配列 for (const name of relativePaths) { - // 各エントリーを記録する + // 各項目を記録する console.log(name); } } @@ -182,13 +168,13 @@ writableStream.write({ type: "seek", position }); writableStream.write({ type: "truncate", size }); ``` -### OPFS 内のファイルを同期式で読み書きする +### OPFS 内のファイルを同期的に読み書きする -この例では、[オリジンプライベートファイルシステム](#%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%B3%E3%83%97%E3%83%A9%E3%82%A4%E3%83%99%E3%83%BC%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0) 内のファイルを同期式で読み書きします。 +この例では、[オリジンプライベートファイルシステム](#オリジンプライベートファイルシステム)内のファイルを同期的に読み書きします。 以下の非同期のイベントハンドラー関数は、ウェブワーカー内にあります。メインスレッドからメッセージを受信した時、以下の処理をします。 -- 同期式のファイルアクセスハンドルを生成する +- 同期的にファイルアクセスハンドルを生成する - ファイルのサイズを取得し、格納するための {{jsxref("ArrayBuffer")}} を生成する - ファイルの内容をバッファーに読み込む - メッセージをエンコードし、ファイルの最後に書き込む @@ -202,7 +188,7 @@ onmessage = async (e) => { // OPFS 内の draft ファイルのハンドルを得る const root = await navigator.storage.getDirectory(); const draftHandle = await root.getFileHandle("draft.txt", { create: true }); - // 同期式のアクセスハンドルを得る + // 同期的にアクセスハンドルを得る const accessHandle = await draftHandle.createSyncAccessHandle(); // ファイルのサイズを得る @@ -224,7 +210,7 @@ onmessage = async (e) => { }; ``` -> **メモ:** 仕様書の以前のバージョンでは、{{domxref("FileSystemSyncAccessHandle.close()", "close()")}}・{{domxref("FileSystemSyncAccessHandle.flush()", "flush()")}}・{{domxref("FileSystemSyncAccessHandle.getSize()", "getSize()")}}・{{domxref("FileSystemSyncAccessHandle.truncate()", "truncate()")}} は人間工学に反して非同期メソッドとされていました。これは現在では[変更されています](https://github.com/whatwg/fs/issues/7)が、まだ非同期バージョンをサポートしているブラウザーもあります。 +> **メモ:** 仕様書の以前のバージョンでは、{{domxref("FileSystemSyncAccessHandle.close()", "close()")}}、{{domxref("FileSystemSyncAccessHandle.flush()", "flush()")}}、{{domxref("FileSystemSyncAccessHandle.getSize()", "getSize()")}}、{{domxref("FileSystemSyncAccessHandle.truncate()", "truncate()")}} は人間工学に反して非同期メソッドとされていました。これは現在では[変更されています](https://github.com/whatwg/fs/issues/7)が、まだ非同期バージョンをサポートしているブラウザーもあります。 ## 仕様書 @@ -236,4 +222,5 @@ onmessage = async (e) => { ## 関連情報 -- [The File System Access API: simplifying access to local files](https://web.dev/file-system-access/) +- [The File System Access API: simplifying access to local files](https://developer.chrome.com/articles/file-system-access/) (web.dev) +- [The origin private file system](https://web.dev/articles/origin-private-file-system) (web.dev) From 67279dc06c7252d773a9f06df322e6640b043935 Mon Sep 17 00:00:00 2001 From: Masahiro FUJIMOTO Date: Fri, 1 Dec 2023 22:52:18 +0900 Subject: [PATCH 2/4] =?UTF-8?q?2023/10/26=20=E6=99=82=E7=82=B9=E3=81=AE?= =?UTF-8?q?=E8=8B=B1=E8=AA=9E=E7=89=88=E3=81=AB=E5=9F=BA=E3=81=A5=E3=81=8D?= =?UTF-8?q?=E6=96=B0=E8=A6=8F=E7=BF=BB=E8=A8=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../origin_private_file_system/index.md | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 files/ja/web/api/file_system_api/origin_private_file_system/index.md diff --git a/files/ja/web/api/file_system_api/origin_private_file_system/index.md b/files/ja/web/api/file_system_api/origin_private_file_system/index.md new file mode 100644 index 00000000000000..b4c2555a0316c6 --- /dev/null +++ b/files/ja/web/api/file_system_api/origin_private_file_system/index.md @@ -0,0 +1,193 @@ +--- +title: オリジンプライベートファイルシステム +slug: Web/API/File_System_API/Origin_private_file_system +page-type: guide +browser-compat: api.StorageManager.getDirectory +--- + +{{securecontext_header}}{{DefaultAPISidebar("File System API")}} + +オリジンプライベートファイルシステム (OPFS) は、[ファイルシステム API](/ja/docs/Web/API/File_System_API) の一部として提供されるストレージエンドポイントです。これは、パフォーマンスのために高度に最適化され、その内容へのその場での書き込みアクセスを提供する特別な種類のファイルへのアクセスを提供します。 + +## ファイルシステムアクセス API を使用したファイルでの作業 + +[ファイルシステムアクセス API](https://wicg.github.io/file-system-access/) は、[ファイルシステム API](/ja/docs/Web/API/File_System_API) を拡張したもので、は、ピッカーメソッドを使ったファイルへのアクセスを提供します。例えば、 + +1. {{domxref("Window.showOpenFilePicker()")}} では、ユーザがアクセスするファイルを選択することができ、その結果、 {{domxref("FileSystemFileHandle")}} オブジェクトが返されます。 +2. {{domxref("FileSystemFileHandle.getFile()")}} を呼び出してファイルの内容にアクセスし、 {{domxref("FileSystemFileHandle.createWritable()")}} / {{domxref("FileSystemWritableFileStream.write()")}} を使用して内容を変更します。 +3. {{domxref("FileSystemHandle.requestPermission()", "FileSystemHandle.requestPermission({mode:'readwrite'})")}} は、変更を保存する許可をユーザーにリクエストするために使用されます。 +4. ユーザーが許可リクエストを受け入れると、変更は元のファイルに保存されます。 + +これは機能しますが、いくつかの制限があります。これらの変更はユーザーから見えるファイルシステムに対して行われるため、悪意のあるコンテンツがファイルシステムに書き込まれないように、多くのセキュリティチェックが行われています(例えば、 Chrome の[セーフブラウジング](https://developers.google.com/safe-browsing))。これらの書き込みはその場で行われるのではなく、一時ファイルを使用します。すべてのセキュリティチェックに合格しない限り、元のファイルは変更されません。 + +その結果、これらの操作はかなり遅くなります。小さなテキストを更新するときにはそれほど気になりませんが、 [SQLite](https://www.sqlite.org/wasm) データベースの変更など、より重要で大規模なファイルを更新するときにはパフォーマンスが低下します。 + +## OPFS はそのような問題をどのように解決するのか + +OPFSは低レベルのバイト単位のファイルアクセスを提供し、ページのオリジンには非公開でユーザーには見えません。そのため、一連のセキュリティチェックや 権限付与を必要とせず、ファイルシステムアクセス API を呼び出すよりも高速です。また、メインスレッドをブロックしないようにウェブワーカーの中だけで実行できる一連の同期呼び出しも利用できます(他のファイルシステム API 呼び出しは非同期です)。 + +OPFS がユーザーから見えるファイルシステムと異なる点をまとめると、次のようになります。 + +- OPFS は、他のオリジン分割されたストレージメカニズム({{domxref("IndexedDB API", "IndexedDB API", "", "nocode")}} など)と同様に、[ブラウザーストレージ容量制限](/ja/docs/Web/API/Storage_API/Storage_quotas_and_eviction_criteria)の対象となります。 OPFS が使用しているストレージ空間の大きさは {{domxref("StorageManager.estimate()", "navigator.storage.estimate()")}} で知ることができます。 +- サイトのストレージデータをクリアすると、 OPFS が削除されます。 +- OPFS のファイルにアクセスするために、その許可のプロンプトやセキュリティチェックは要求されません。 +- ブラウザーは OPFS の内容をディスクのどこかに保持しますが、作成したファイルを 1 対 1 で照合して探すことはできません。 OPFS はユーザーから見えることを意図していません。 + +## OPFS にはどのようにアクセスするのか + +最初の OPFS にアクセスするには、 {{domxref("StorageManager.getDirectory()", "navigator.storage.getDirectory()")}} メソッドを呼び出します。これは、 OPFS のルートを表す {{domxref("FileSystemDirectoryHandle")}} オブジェクトへの参照を返します。 + +## メインスレッドからの OPFS の操作 + +メインスレッドから OPFS にアクセスする場合は、非同期の {{jsxref("Promise")}} ベースの API を使用します。ファイル({{domxref("FileSystemFileHandle")}})とディレクトリー({{domxref("FileSystemDirectoryHandle")}})のハンドルにアクセスするには、 {{domxref("FileSystemDirectoryHandle.getFileHandle()")}} と {{domxref("FileSystemDirectoryHandle.getDirectoryHandle()")}} をそれぞれ、 OPFS ルート(および作成された子ディレクトリー)を表す {{domxref("FileSystemDirectoryHandle")}} オブジェクト上で呼び出します。 + +> **メモ:** 上記のメソッドに `{ create: true }` を渡すと、ファイルやフォルダー内が存在しない場合に作成されます。 + +```js +// ファイルとフォルダー内の階層を作成 +const fileHandle = await opfsRoot + .getFileHandle('my first file', {create: true}); +const directoryHandle = await opfsRoot + .getDirectoryHandle('my first folder', {create: true}); +const nestedFileHandle = await directoryHandle + .getFileHandle('my first nested file', {create: true}); +const nestedDirectoryHandle = await directoryHandle + .getDirectoryHandle('my first nested folder', {create: true}); + +// 既存のファイル名やフォルダー内にアクセス +const existingFileHandle = await opfsRoot.getFileHandle('my first file'); +const existingDirectoryHandle = await opfsRoot + .getDirectoryHandle('my first folder'); +``` + +### ファイルの読み取り + +1. {{domxref("FileSystemDirectoryHandle.getFileHandle()")}} を呼び出すと {{domxref("FileSystemFileHandle")}} オブジェクトが返ります。 +2. {{domxref("FileSystemFileHandle.getFile()")}} を呼び出すと {{domxref("File")}} オブジェクトが返ります。これは {{domxref("Blob")}} の特化した型なので、他の `Blob` と同じように操作できます。例えば、 {{domxref("Blob.text()")}} で直接テキストコンテンツにアクセスすることができます。 + +### ファイルへの書き込み + +1. {{domxref("FileSystemDirectoryHandle.getFileHandle()")}} を呼び出すと {{domxref("FileSystemFileHandle")}} オブジェクトが返ります。 +2. {{domxref("FileSystemFileHandle.createWritable()")}} を呼び出すと {{domxref("FileSystemWritableFileStream")}} オブジェクトが返ります。これは {{domxref("WritableStream")}} の特化した型です。 +3. {{domxref("FileSystemWritableFilestream.write()")}} を呼び出して内容を書き込みます。 +4. {{domxref("WritableStream.close()")}} を使用してストリームを閉じます。 + +### ファイルまたはフォルダーの削除 + +親ディレクトリーで {{domxref("FileSystemDirectoryHandle.removeEntry()")}} を呼び出して、削除したい項目の名前を渡します。 + +```js +directoryHandle.removeEntry("my first nested file"); +``` + +また、 {{domxref("FileSystemHandle.remove()")}} を {{domxref("FileSystemFileHandle")}} または {{domxref("FileSystemDirectoryHandle")}} で呼び出すこともできます。すべてのサブフォルダーを含めてフォルダー内を削除するには、 `{ recursive: true }` オプションを渡してください。 + +```js +await fileHandle.remove(); +await directoryHandle.remove({ recursive: true }); +``` + +以下は、 OPFS 全体をクリアする簡単な方法です: + +```js +await (await navigator.storage.getDirectory()).remove({ recursive: true }); +``` + +### フォルダーの内容の一覧出力 + +{{domxref("FileSystemDirectoryHandle")}} は[非同期イテレーター](/ja/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols)です。そのため、 [`for await…of`](/ja/docs/Web/JavaScript/Reference/Statements/for-await...of) ループや、[`entries()`](/ja/docs/Web/API/FileSystemDirectoryHandle/entries), [`values()`](/ja/docs/Web/API/FileSystemDirectoryHandle/entries), [`keys()`](/ja/docs/Web/API/FileSystemDirectoryHandle/entries) などの標準メソッドで反復処理することができます。 + +例えば次のようにします。 + +```js +for await (let [name, handle] of directoryHandle) { +} +for await (let [name, handle] of directoryHandle.entries()) { +} +for await (let handle of directoryHandle.values()) { +} +for await (let name of directoryHandle.keys()) { +} +``` + +## ウェブワーカーにおける OPFS の操作 + +ウェブ ワーカーはメインスレッドをブロックしないので、このコンテキストで同期ファイル アクセス API を使用することができます。同期 API はプロミスを扱う必要がないため、より高速です。 + +同期的にファイルにアクセスするには、 {{domxref("FileSystemFileHandle.createSyncAccessHandle()")}} を通常の {{domxref("FileSystemFileHandle")}} に対して呼び出します。 + +> **メモ:** 名前に "Sync" とあるにもかかわらず、`createSyncAccessHandle()` メソッド自体は非同期です。 + +```js +const opfsRoot = await navigator.storage.getDirectory(); +const fileHandle = await opfsRoot.getFileHandle("my highspeed file.txt", { + create: true, +}); +const syncAccessHandle = await fileHandle.createSyncAccessHandle(); +``` + +返される {{domxref("FileSystemSyncAccessHandle")}} で利用できる同期メソッドがいくつかあります。 + +- {{domxref("FileSystemSyncAccessHandle.getSize", "getSize()")}}: ファイルのサイズをバイト数で返します。 +- {{domxref("FileSystemSyncAccessHandle.write", "write()")}}: バッファーの内容を指定されたオフセットを指定してファイルに書き込み、書き込んだバイト数を返します。返された書き込みバイト数を調べることで、呼び出し側はエラーや部分的な書き込みを検出して処理することができます。 +- {{domxref("FileSystemSyncAccessHandle.read", "read()")}}: オプションで指定されたオフセットで、ファイルの内容をバッファーに読み込みます。 +- {{domxref("FileSystemSyncAccessHandle.truncate", "truncate()")}}: 指定されたサイズにファイルをリサイズします。 +- {{domxref("FileSystemSyncAccessHandle.flush", "flush()")}}: `write()` によって行われたすべての変更がファイルの内容に格納されていることを保証します。 +- {{domxref("FileSystemSyncAccessHandle.close", "close()")}}: アクセスハンドルを閉じます。 + +この例では、上記のメソッドをすべて使用しています。 + +```js +const opfsRoot = await navigator.storage.getDirectory(); +const fileHandle = await opfsRoot.getFileHandle("fast", { create: true }); +const accessHandle = await fileHandle.createSyncAccessHandle(); + +const textEncoder = new TextEncoder(); +const textDecoder = new TextDecoder(); + +// ファイルのサイズのための変数の初期化 +let size; +// ファイルの現在のサイズ。初期値は `0`。 +size = accessHandle.getSize(); +// ファイルに書き込むためにコンテンツをエンコード +const content = textEncoder.encode("Some text"); +// ファイルの先頭にコンテンツを書き込む +accessHandle.write(content, { at: size }); +// 変更をフラッシュする +accessHandle.flush(); +// ファイルの現在のサイズ、これで `9`("Some text" の長さ) +size = accessHandle.getSize(); + +// ファイルに書き込むために、さらにコンテンツをエンコード +const moreContent = textEncoder.encode("More content"); +// ファイルの最後にコンテンツを書き込む +accessHandle.write(moreContent, { at: size }); +// 変更をフラッシュする +accessHandle.flush(); +// これで現在のファイルサイズは `21`("Some textMore content" の長さ)となる +size = accessHandle.getSize(); + +// ファイルの長さのデータビューを準備 +const dataView = new DataView(new ArrayBuffer(size)); + +// ファイル全体をデータビューに読み込む +accessHandle.read(dataView); +// `"Some textMore content"` とログ出力 +console.log(textDecoder.decode(dataView)); + +// オフセット 9 から始め、データビューに読み込む。 +accessHandle.read(dataView, { at: 9 }); +// `"More content"` とログ出力 +console.log(textDecoder.decode(dataView)); + +// ファイルを 4 バイトで切り捨てる。 +accessHandle.truncate(4); +``` + +## ブラウザーの互換性 + +{{Compat}} + +## 関連情報 + +- [The origin private file system](https://web.dev/articles/origin-private-file-system) (web.dev) From 150adabe2009d989e4b5a337d6b9eeec3989f76d Mon Sep 17 00:00:00 2001 From: Masahiro FUJIMOTO Date: Fri, 1 Dec 2023 23:10:50 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=E3=83=98=E3=83=83=E3=83=80=E3=83=BC?= =?UTF-8?q?=E9=83=A8=E5=88=86=E3=81=AE=E6=9B=B4=E6=96=B0=E5=BF=98=E3=82=8C?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/file_system_api/origin_private_file_system/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/ja/web/api/file_system_api/origin_private_file_system/index.md b/files/ja/web/api/file_system_api/origin_private_file_system/index.md index b4c2555a0316c6..70f2d7af2e7848 100644 --- a/files/ja/web/api/file_system_api/origin_private_file_system/index.md +++ b/files/ja/web/api/file_system_api/origin_private_file_system/index.md @@ -1,8 +1,8 @@ --- title: オリジンプライベートファイルシステム slug: Web/API/File_System_API/Origin_private_file_system -page-type: guide -browser-compat: api.StorageManager.getDirectory +l10n: + sourceCommit: 835d6632d59993861a0458510402787f8a2c3cb3 --- {{securecontext_header}}{{DefaultAPISidebar("File System API")}} From 77fc29c1b082031deb32cb20cf0e69a73ee7e382 Mon Sep 17 00:00:00 2001 From: Masahiro FUJIMOTO Date: Fri, 1 Dec 2023 23:13:51 +0900 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../origin_private_file_system/index.md | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/files/ja/web/api/file_system_api/origin_private_file_system/index.md b/files/ja/web/api/file_system_api/origin_private_file_system/index.md index 70f2d7af2e7848..85c03de5a5179d 100644 --- a/files/ja/web/api/file_system_api/origin_private_file_system/index.md +++ b/files/ja/web/api/file_system_api/origin_private_file_system/index.md @@ -45,19 +45,25 @@ OPFS がユーザーから見えるファイルシステムと異なる点をま ```js // ファイルとフォルダー内の階層を作成 -const fileHandle = await opfsRoot - .getFileHandle('my first file', {create: true}); -const directoryHandle = await opfsRoot - .getDirectoryHandle('my first folder', {create: true}); -const nestedFileHandle = await directoryHandle - .getFileHandle('my first nested file', {create: true}); -const nestedDirectoryHandle = await directoryHandle - .getDirectoryHandle('my first nested folder', {create: true}); +const fileHandle = await opfsRoot.getFileHandle("my first file", { + create: true, +}); +const directoryHandle = await opfsRoot.getDirectoryHandle("my first folder", { + create: true, +}); +const nestedFileHandle = await directoryHandle.getFileHandle( + "my first nested file", + { create: true }, +); +const nestedDirectoryHandle = await directoryHandle.getDirectoryHandle( + "my first nested folder", + { create: true }, +); // 既存のファイル名やフォルダー内にアクセス -const existingFileHandle = await opfsRoot.getFileHandle('my first file'); -const existingDirectoryHandle = await opfsRoot - .getDirectoryHandle('my first folder'); +const existingFileHandle = await opfsRoot.getFileHandle("my first file"); +const existingDirectoryHandle = + await opfsRoot.getDirectoryHandle("my first folder"); ``` ### ファイルの読み取り