FileSystemFileHandle: createWritable() 方法
注意:此功能在Web Workers 中可用。
createWritable()
方法是 FileSystemFileHandle
接口的一部分,它创建一个 FileSystemWritableFileStream
,可用于写入文件。该方法返回一个 Promise
,该 Promise 解析为创建的流。
通过流进行的任何更改都不会反映在文件句柄代表的文件中,直到流关闭。这通常通过将数据写入临时文件来实现,并且仅在可写文件流关闭时用临时文件替换文件句柄代表的文件。
语法
createWritable()
createWritable(options)
参数
options
可选-
具有以下属性的对象
keepExistingData
可选-
一个
Boolean
。默认值为false
。当设置为true
时,如果文件存在,则先将现有文件复制到临时文件。否则,临时文件将为空。 mode
可选 非标准-
一个字符串,指定可写文件流的锁定模式。默认值为
"siloed"
。可能的值为"exclusive"
-
只能打开一个
FileSystemWritableFileStream
写入器。在第一个写入器关闭之前尝试打开后续写入器会导致抛出NoModificationAllowedError
异常。 "siloed"
-
可以在同一时间打开多个
FileSystemWritableFileStream
写入器,每个写入器都有自己的交换文件,例如在多个选项卡中使用同一个应用程序时。最后一个打开的写入器将写入其数据,因为数据在每个写入器关闭时被刷新。
返回值
一个 Promise
,它解析为一个 FileSystemWritableFileStream
对象。
异常
NotAllowedError
DOMException
-
如果句柄的
PermissionStatus.state
不是'granted'
的读写模式,则抛出该异常。 NotFoundError
DOMException
-
如果找不到当前条目,则抛出该异常。
NoModificationAllowedError
DOMException
-
如果浏览器无法获取与文件句柄关联的文件的锁,则抛出该异常。这可能是因为
mode
设置为exclusive
,并且尝试同时打开多个写入器。 AbortError
DOMException
-
如果实现定义的恶意软件扫描和安全浏览检查失败,则抛出该异常。
示例
基本用法
以下异步函数将给定内容写入文件句柄,从而写入磁盘。
async function writeFile(fileHandle, contents) {
// Create a FileSystemWritableFileStream to write to.
const writable = await fileHandle.createWritable();
// Write the contents of the file to the stream.
await writable.write(contents);
// Close the file and write the contents to disk.
await writable.close();
}
使用选项的扩展用法
我们的 createWritable()
模式测试 示例提供了一个 <button>
来选择要写入的文件,一个文本 <input>
字段,您可以在其中输入一些要写入文件的文本,以及第二个 <button>
来将文本写入文件。
在上面的演示中,尝试在您的文件系统上选择一个文本文件(或输入一个新文件名),在输入字段中输入一些文本,并将文本写入文件。打开文件系统上的文件以检查写入是否成功。
此外,尝试在两个浏览器选项卡中同时打开页面。在第一个选项卡中选择一个要写入的文件,然后立即尝试在第二个选项卡中选择同一个文件进行写入。您应该会收到一条错误消息,因为我们在 createWritable()
调用中设置了 mode: "exclusive"
。
下面我们将探讨代码。
HTML
两个 <button>
元素和文本 <input>
字段如下所示
<ol>
<li>
Select a file to write to: <button class="select">Select file</button>
</li>
<li>
<label for="filetext">Enter text to write to the file:</label>
<input type="text" id="filetext" name="filetext" disabled />
</li>
<li>
Write your text to the file:
<button class="write" disabled>Write text</button>
</li>
</ol>
文本输入字段和写入文本按钮最初通过 disabled
属性设置为禁用状态 - 在用户选择要写入的文件之前,不应使用它们。
JavaScript
我们首先获取选择文件按钮、写入文本按钮和文本输入字段的引用。我们还声明了一个全局变量 writableStream
,它将在创建后存储对用于将文本写入文件的可写流的引用。我们最初将其设置为 null
。
const selectBtn = document.querySelector(".select");
const writeBtn = document.querySelector(".write");
const fileText = document.querySelector("#filetext");
let writableStream = null;
接下来,我们创建一个名为 selectFile()
的异步函数,我们将在按下选择按钮时调用它。这使用 Window.showSaveFilePicker()
方法向用户显示一个文件选择器对话框,并创建一个指向他们选择的文件的文件句柄。在这个句柄上,我们调用 createWritable()
方法来创建一个流,将文本写入所选文件。如果调用失败,我们将错误记录到控制台。
我们将包含以下选项的选项对象传递给 createWritable()
keepExistingData: true
: 如果所选文件已存在,则在写入开始之前,其包含的数据将被复制到临时文件。mode: "exclusive"
: 指明文件句柄上一次只能打开一个写入器。如果第二个用户加载示例并尝试选择文件,他们将收到错误。
最后,我们启用输入字段和写入文本按钮,因为它们是下一步所需的,并禁用选择文件按钮(目前不需要)。
async function selectFile() {
// Create a new handle
const handle = await window.showSaveFilePicker();
// Create a FileSystemWritableFileStream to write to
try {
writableStream = await handle.createWritable({
keepExistingData: true,
mode: "exclusive",
});
} catch (e) {
if (e.name === "NoModificationAllowedError") {
console.log(
`You can't access that file right now; someone else is trying to modify it. Try again later.`,
);
} else {
console.log(e.message);
}
}
// Enable text field and write button, disable select button
fileText.disabled = false;
writeBtn.disabled = false;
selectBtn.disabled = true;
}
我们的下一个函数 writeFile()
使用 FileSystemWritableFileStream.write()
将输入字段中输入的文本写入选定的文件,然后清空输入字段。然后,我们使用 WritableStream.close()
关闭可写流,并重置演示,使其可以再次运行 - 控件的 disabled
状态切换回其原始状态,writableStream
变量重置为 null
。
async function writeFile() {
// Write text to our file and empty out the text field
await writableStream.write(fileText.value);
fileText.value = "";
// Close the file and write the contents to disk.
await writableStream.close();
// Disable text field and write button, enable select button
fileText.disabled = true;
writeBtn.disabled = true;
selectBtn.disabled = false;
// Set writableStream back to null
writableStream = null;
}
要使演示运行,我们为按钮设置事件监听器,以便在单击每个按钮时运行相关函数。
selectBtn.addEventListener("click", selectFile);
writeBtn.addEventListener("click", writeFile);
规范
规范 |
---|
文件系统标准 # api-filesystemfilehandle-createwritable |
浏览器兼容性
BCD 表格仅在启用 JavaScript 的浏览器中加载。