FileSystemApi 和 writableStream

FileSystemApi and writableStream

我正在尝试使用文件系统 API 将 SPA 上的上传文件写入使用文件系统 API 的本地沙盒文件系统。

文件是用 drop acion 上传的,我可以在回调中得到 File 对象数组。 从 File 我可以得到 ReadableStream 调用 stream 方法(是的,它 return 只可读)。

考虑到上传的文件可能足够大,我会选择流式传输而不是完全加载到 blob 中然后写入文件系统 api。

所以,按照文档的步骤是:

  1. 通过异步 webkitRequestFileSystem 调用获取 FileSystem (DOMFileSystem)。
  2. 获取作为 FileSystemDirectoryEntry
  3. 的道具 root
  4. 通过 getFile 创建一个文件(带有标志 create:true),returns(异步)一个 FileSystemFileEntry

现在从 FileEntry 我可以使用 createWriter 获得一个 FileWriter 但它已经过时(在 MDN 中),无论如何它是一个 FileWriter 而我希望获得一个 WritableStream为了使用上传文件中的 pipeTo Handler->ReadableStream.

所以,我看到在控制台中定义了 class(接口)FileSystemFileHandler,但我不明白如何从 FileSystemFileEntry 获取实例。如果我可以获得一个 FileSystemFileHandler,我可以调用 createWritable 来获得一个 FileSystemWritableFileStream,我可以用 ReadStream 进行“管道传输”。

谁能澄清一下这个烂摊子?

参考资料: https://web.dev/file-system-access/ https://wicg.github.io/file-system-access/#filesystemhandle https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileEntry

您在底部的“参考资料”链接中找到了解决方案。具体来说,就是这个section来读。您可以像这样创建文件或目录:

// In an existing directory, create a new directory named "My Documents".
const newDirectoryHandle = await existingDirectoryHandle.getDirectoryHandle('My Documents', {
  create: true,
});
// In this new directory, create a file named "My Notes.txt".
const newFileHandle = await newDirectoryHandle.getFileHandle('My Notes.txt', { create: true });

获得文件句柄后,您可以通过管道传输或写入:

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();
}

……或者……

async function writeURLToFile(fileHandle, url) {
  // Create a FileSystemWritableFileStream to write to.
  const writable = await fileHandle.createWritable();
  // Make an HTTP request for the contents.
  const response = await fetch(url);
  // Stream the response into the file.
  await response.body.pipeTo(writable);
  // pipeTo() closes the destination pipe by default, no need to close it.
}