Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[zh-CN] Init FileSystemFileHandle #15505

Merged
merged 9 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions files/zh-cn/web/api/file_system_api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ slug: Web/API/File_System_API
- {{domxref('HTML Drag and Drop API', 'HTML 拖放 API', '', 'nocode')}} 的 {{domxref('DataTransferItem.getAsFileSystemHandle()')}} 方法。
- [文件处理 API](https://developer.chrome.com/en/articles/file-handling/)。

每种句柄都提供了其独有的功能,取决于你使用的种类,会有些许差异(详见[接口](#接口)部分)。在获得句柄后,你便可以访问文件的数据或是被选中的目录的信息(包含子目录)。此 API 开辟了 web 此前一直缺乏的潜在功能。但不论如何,安全性是设计 API 时的首要考量,除非用户明确授权,否则就不允许访问文件和目录的数据。
每种句柄都提供了其独有的功能,取决于你使用的种类,会有些许差异(详见[接口](#接口)部分)。在获得句柄后,你便可以访问文件的数据或是被选中的目录的信息(包含子目录)。此 API 开辟了 web 此前一直缺乏的潜在功能。但不论如何,安全性是设计 API 时的首要考量,除非用户明确授权,否则就不允许访问文件和目录的数据(注意:[源私有文件系统](#源私有文件系统)并非如此,因为其对用户不可见)

> **备注:** 使用此 API 的特性时可能会抛出的各种异常已在规范定义的相关页面中列出。然而,API 与底层操作系统的交互使得实际情况更加复杂。这里提供一篇关于[在规范中列出错误对应表](https://github.com/whatwg/fs/issues/57)的提议,其中包含了一些有用的信息。

Expand All @@ -46,7 +46,7 @@ slug: Web/API/File_System_API
- {{domxref("FileSystemDirectoryHandle")}}
- : 提供一个文件系统目录的句柄。
- {{domxref("FileSystemSyncAccessHandle")}}
- : 提供一个文件系统条目的同步句柄,用于在磁盘上原地操作单个文件。其在文件读写上的同步特性可在异步操作开销较大的情景中使关键方法拥有更优秀的性能,例如 [WebAssembly](/zh-CN/docs/WebAssembly)。此类只能在 [Web Worker](/zh-CN/docs/Web/API/Web_Workers_API) 中操作[源私有文件系统](#源私有文件系统)上的文件时访问
- : 提供一个文件系统条目的同步句柄,用于在磁盘上原地操作单个文件。其在文件读写上的同步特性可在异步操作开销较大的情景中使关键方法拥有更优秀的性能,例如 [WebAssembly](/zh-CN/docs/WebAssembly)。此类只能在专用于操作[源私有文件系统](#源私有文件系统)上的文件的 [Web Worker](/zh-CN/docs/Web/API/Web_Workers_API) 中访问
- {{domxref("FileSystemWritableFileStream")}}
- : 属于 {{domxref('WritableStream')}} 对象,附加了便于操作磁盘上单个文件的方法。

Expand Down Expand Up @@ -174,7 +174,7 @@ writableStream.write({ type: "truncate", size });

- 创建一个异步文件访问句柄。
- 获取文件大小并创建一个 {{jsxref("ArrayBuffer")}} 来容纳它。
- 将文件内容读取到 buffer 中
- 将文件内容读取到缓冲区中
- 将消息编码,并将其写入到文件末尾。
- 将更改持久化至磁盘并关闭访问句柄。

Expand All @@ -183,15 +183,15 @@ onmessage = async (e) => {
// 获取从主线程发往 worker 的消息
const message = e.data;

// 获取 OPFS 中 draft 文件的句柄
// 获取 OPFS 中草稿文件的句柄
const root = await navigator.storage.getDirectory();
const draftHandle = await root.getFileHandle("draft.txt", { create: true });
// 获取同步访问句柄
const accessHandle = await draftHandle.createSyncAccessHandle();

// 获取文件大小
const fileSize = accessHandle.getSize();
// 将文件内容读取到 buffer
// 将文件内容读取到缓冲区
const buffer = new DataView(new ArrayBuffer(fileSize));
const readBuffer = accessHandle.read(buffer, { at: 0 });

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: FileSystemFileHandle:createSyncAccessHandle() 方法
slug: Web/API/FileSystemFileHandle/createSyncAccessHandle
---

{{securecontext_header}}{{APIRef("File System API")}}

{{domxref("FileSystemFileHandle")}} 接口的 **`createSyncAccessHandle()`** 方法返回一个 {{jsxref('Promise')}} 对象,可兑现一个用于同步读写文件的 {{domxref('FileSystemSyncAccessHandle')}} 对象。此方法的同步特性带来了性能优势,但是只能在专用于操作[源私有文件系统](/zh-CN/docs/Web/API/File_System_API/Origin_private_file_system)上的文件的 [Web Worker](/zh-CN/docs/Web/API/Web_Workers_API) 中使用。

创建 {{domxref('FileSystemSyncAccessHandle')}} 会对与文件句柄关联的文件进行独占锁定。这用于在文件已有的访问句柄被关闭前,阻止对文件创建更多的 {{domxref('FileSystemSyncAccessHandle')}} 或 {{domxref('FileSystemWritableFileStream')}}。

## 语法

```js-nolint
createSyncAccessHandle()
```

### 参数

无。

### 返回值

一个 {{jsxref('Promise')}} 对象,可兑现一个 {{domxref('FileSystemSyncAccessHandle')}} 对象。

### 异常

- `InvalidStateError` {{domxref("DOMException")}}
- : 如果 {{domxref('FileSystemSyncAccessHandle')}} 对象代表的不是[源私有文件系统](/zh-CN/docs/Web/API/File_System_API/Origin_private_file_system)上的文件,抛出此异常。
- `NoModificationAllowedError` {{domxref("DOMException")}}
- : 如果浏览器无法获得文件句柄所关联的文件的锁定,抛出此异常。
- `NotAllowedError` {{domxref("DOMException")}}
- : 如果在 API 层面上没有被授予权限(也就是需要调用 {{domxref("FileSystemHandle.requestPermission")}}),抛出此异常。

## 示例

以下异步事件处理函数处于 Web Worker 上下文。其中的代码片段创建了一个同步文件访问句柄。

```js
onmessage = async (e) => {
// 获取从主线程发往 worker 的消息
const message = e.data;

// 获取草稿文件的句柄
const root = await navigator.storage.getDirectory();
const draftHandle = await root.getFileHandle("draft.txt", { create: true });
// 获取同步访问句柄
const accessHandle = await draftHandle.createSyncAccessHandle();

// ……

// 用完 FileSystemSyncAccessHandle 记得把它关闭
accessHandle.close();
};
```

## 规范

{{Specifications}}

## 浏览器兼容性

{{Compat}}

## 参见

- [文件系统 API](/zh-CN/docs/Web/API/File_System_API)
- [文件系统访问 API:简化本地文件访问](https://web.dev/file-system-access/)
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
title: FileSystemFileHandle:createWritable() 方法
slug: Web/API/FileSystemFileHandle/createWritable
---

{{securecontext_header}}{{APIRef("File System API")}}

{{domxref("FileSystemFileHandle")}} 接口的 **`createWritable()`** 方法用于创建一个 {{domxref('FileSystemWritableFileStream')}} 对象,可用于写入文件。此方法返回一个可兑现这些写入流的 {{jsxref('Promise')}} 对象。

任何通过写入流造成的更改在写入流被关闭前都不会反映到文件句柄所代表的文件上。这通常是将数据写入到一个临时文件来实现的,然后只有在写入文件流被关闭后才会用临时文件替换掉文件句柄所代表的文件。

## 语法

```js-nolint
createWritable()
createWritable(options)
```

### 参数

- `options` {{optional_inline}}

- : 一个包含以下属性的对象:

- `keepExistingData`
- : {{jsxref('Boolean', '布尔值', '', 'nocode')}},默认为 `false`。当设为 `true` 时,如果文件存在,则现将现有文件的内容复制到临时文件,否则临时文件初始时内容为空。

### 返回值

一个 {{jsxref('Promise')}} 对象,可兑现一个 {{domxref('FileSystemWritableFileStream')}} 对象。

### 异常

- NotAllowedError
- : 如果句柄 `readwrite` 模式的 {{domxref('PermissionStatus.state')}} 不为 `'granted'`,则抛出此异常。

## 示例

以下异步函数用于将给定内容写入文件句柄,从而写入磁盘。

```js
async function writeFile(fileHandle, contents) {
// 创建一个 FileSystemWritableFileStream 用来写入。
const writable = await fileHandle.createWritable();

// 将文件内容写入到流中。
await writable.write(contents);

// 关闭文件并将内容写入磁盘。
await writable.close();
}
```

## 规范

{{Specifications}}

## 浏览器兼容性

{{Compat}}

## 参见

- [文件系统 API](/zh-CN/docs/Web/API/File_System_API)
- [文件系统访问 API:简化本地文件访问](https://web.dev/file-system-access/)
56 changes: 56 additions & 0 deletions files/zh-cn/web/api/filesystemfilehandle/getfile/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: FileSystemFileHandle:getFile() 方法
slug: Web/API/FileSystemFileHandle/getFile
---

{{securecontext_header}}{{APIRef("File System API")}}

{{domxref("FileSystemFileHandle")}} 接口的 **`getFile()`** 方法返回一个 {{jsxref('Promise')}} 对象,可兑现一个 {{domxref('File')}} 对象,其表示磁盘上句柄所代表的条目的状态。

如果磁盘上的文件在调用了此方法后发生了更改或是被移除,那么返回的 {{domxref('File')}} 对象可能会不再可读。

## 语法

```js-nolint
getFile()
```

### 参数

无。

### 返回值

一个 {{jsxref('Promise')}} 对象,可兑现一个 {{domxref('File')}} 对象。

### 异常

- NotAllowedError
- : 如果只读模式的 {{domxref('PermissionStatus.state')}} 不是 `granted` ,则抛出此异常。

## 示例

下面的异步函数可以显示一个文件选择器,并在选择了文件时使用 `getFile()` 方法取得内容。

```js
async function getTheFile() {
// 打开文件选择器
const [fileHandle] = await window.showOpenFilePicker(pickerOpts);

// 获取文件内容
const fileData = await fileHandle.getFile();
}
```

## 规范

{{Specifications}}

## 浏览器兼容性

{{Compat}}

## 参见

- [文件系统 API](/zh-CN/docs/Web/API/File_System_API)
- [文件系统访问 API:简化本地文件访问](https://web.dev/file-system-access/)
128 changes: 128 additions & 0 deletions files/zh-cn/web/api/filesystemfilehandle/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
---
title: FileSystemFileHandle
slug: Web/API/FileSystemFileHandle
---

{{securecontext_header}}{{APIRef("File System API")}}

{{domxref("File System API", "File System API", "", "nocode")}} 的 **`FileSystemFileHandle`** 接口表示一个指向文件系统条目的句柄。可通过 {{domxref('window.showOpenFilePicker()')}} 方法来访问此接口。

注意,读写操作所依赖的文件访问权限在刷新或关闭页面并且页面所属的源没有其他标签页保持打开的情况下不会继续保有。{{domxref("FileSystemHandle")}} 接口的 {{domxref("FileSystemHandle.queryPermission()", "queryPermission")}} 方法可用于在访问文件前验证权限状态。

{{InheritanceDiagram}}

## 实例属性

_从父类 {{DOMxRef("FileSystemHandle")}} 继承属性。_

## 实例方法

_从父类 {{DOMxRef("FileSystemHandle")}} 继承方法。_

- {{domxref('FileSystemFileHandle.getFile', 'getFile()')}}
- : 返回一个 {{jsxref('Promise')}} 对象,可兑现一个 {{domxref('File')}} 对象,该对象表示句柄所代表的的条目在磁盘上的状态。
- {{domxref('FileSystemFileHandle.createSyncAccessHandle', 'createSyncAccessHandle()')}}
- : 返回一个 {{jsxref('Promise')}} 对象,可兑现一个 {{domxref('FileSystemSyncAccessHandle')}} 对象,该对象可用于同步读写文件。此方法的同步特性带来了性能优势,但是只能在专用的 [Web Worker](/zh-CN/docs/Web/API/Web_Workers_API) 中使用。
- {{domxref('FileSystemFileHandle.createWritable', 'createWritable()')}}
- : 返回一个 {{jsxref('Promise')}} 对象,可兑现一个新建的 {{domxref('FileSystemWritableFileStream')}} 对象,可用于写入文件。

## 示例

### 读取文件

下面的异步函数用于显示一个文件选择器,一旦有文件被选择,便可以使用 `getFile()` 方法获取其内容。

```js
async function getTheFile() {
const pickerOpts = {
types: [
{
description: "Images",
accept: {
"image/*": [".png", ".gif", ".jpeg", ".jpg"],
},
},
],
excludeAcceptAllOption: true,
multiple: false,
};

// 打开文件选择器
const [fileHandle] = await window.showOpenFilePicker(pickerOpts);
// 获取文件内容
const fileData = await fileHandle.getFile();
return fileData;
}
```

### 写入文件

以下异步函数用于将给定内容写入文件句柄,从而写入磁盘。

```js
async function writeFile(fileHandle, contents) {
// 创建一个 FileSystemWritableFileStream 用来写入。
const writable = await fileHandle.createWritable();

// 将文件内容写入到流中。
await writable.write(contents);

// 关闭文件并将内容写入磁盘。
await writable.close();
}
```

### 同步读写文件

以下异步事件处理函数处于 Web Worker 上下文,从主线程接收消息。

- 创建一个异步文件访问句柄。
- 获取文件大小并创建一个 {{jsxref("ArrayBuffer")}} 来容纳它。
- 将文件内容读取到缓冲区中。
- 将消息编码,并将其写入到文件末尾。
- 将更改持久化至磁盘并关闭访问句柄。

```js
onmessage = async (e) => {
// 获取从主线程发往 worker 的消息
const message = e.data;

// 获取草稿文件的句柄
const root = await navigator.storage.getDirectory();
const draftHandle = await root.getFileHandle("draft.txt", { create: true });
// 获取同步访问句柄
const accessHandle = await draftHandle.createSyncAccessHandle();

// 获取文件大小
const fileSize = accessHandle.getSize();
// 将文件内容读取到缓冲区
const buffer = new DataView(new ArrayBuffer(fileSize));
const readBuffer = accessHandle.read(buffer, { at: 0 });

// 将消息写入到文件末尾
const encoder = new TextEncoder();
const encodedMessage = encoder.encode(message);
const writeBuffer = accessHandle.write(encodedMessage, { at: readBuffer });

// 将更改持久化至磁盘
accessHandle.flush();

// 用完 FileSystemSyncAccessHandle 记得把它关闭
accessHandle.close();
};
```

> **备注:** 在规范早期版本中,{{domxref("FileSystemSyncAccessHandle.close()", "close()")}}、{{domxref("FileSystemSyncAccessHandle.flush()", "flush()")}}、{{domxref("FileSystemSyncAccessHandle.getSize()", "getSize()")}} 和 {{domxref("FileSystemSyncAccessHandle.truncate()", "truncate()")}} 被错误地定义为异步方法。此问题现已被[修正](https://github.com/whatwg/fs/issues/7),但某些浏览器依然支持异步版本。

## 规范

{{Specifications}}

## 浏览器兼容性

{{Compat}}

## 参见

- [文件系统 API](/zh-CN/docs/Web/API/File_System_API)
- [文件系统访问 API:简化本地文件访问](https://web.dev/file-system-access/)