File System Access API 前端实现文件系统

文件系统访问 API 是一种网页 API, 允许访问和修改用户本地的文件。网页前端可以轻松的实现导入与导出功能。下面让我们一起来看看如何开始使用这个 API。

读取文件

在我们深入研究从用户系统中读取文件的代码之前,需要注意:调用文件系统访问 API 必须通过用户操作触发,并在安全的上下文中进行。 在下面的例子中,我们将在点击事件中调用该 API。

读取单个文件

从一个文件中读取数据,代码不到 10 行就可以实现。示例如下:

ini 复制代码
 let fileHandle;

 document.querySelector(".pick-file-button").onclick = async () => {
  [fileHandle] = await window.showOpenFilePicker();

  const file = await fileHandle.getFile();
  const content = await file.text();

  return content;
 };

假设我们在 HTML 中有一个 class 为 .pick-file-button 的按钮。当点击这个按钮时,我们通过调用 window.showOpenFilePicker() 启动文件选择器,并将返回结果存储在一个名为 fileHandle 的变量中。

调用 showOpenFilePicker() 返回的是表示所选文件的 FileSystemFileHandle 对象数组。

这些对象包含 kind 和 name 属性。如果打印 console.log(fileHandle), 你会看到如下对象:

css 复制代码
 FileSystemFileHandle {kind: 'file', name: 'data.txt'}

kind 属性的值可以是 file 或者 directory。

在 fileHandle 对象上,我们可以调用 getFile () 方法来获取文件详情。

调用这个方法会返回一个对象,包含文件最后修改时间、文件名、大小和类型等属性。

最后,我们可以在文件对象上调用 text () 方法获取文件内容。

读取多个文件

如果要读取多个文件,我们需要向 showOpenFilePicker () 传入一个 options 对象。

例如:

dart 复制代码
 let fileHandles;
 const options = {
  multiple: true,
 };

 document.querySelector(".pick-file-button").onclick = async () => {
  fileHandles = await window.showOpenFilePicker(options);

  // The rest of the code will be shown below
 };

默认情况下,multiple 属性为 false。我们还可以通过选项指明可选择的文件类型。

例如,如果只希望选择 .jpeg 文件,options 对象会包含以下内容:

css 复制代码
 const options = {
  types: [
    {
      description: "Images",
      accept: {
        "image/jpeg": ".jpeg",
      },
    },
  ],
  excludeAcceptAllOption: true,
 };

示例中,fileHandles得到的是一个包含多个文件的数组,获取内容的方法如下:

ini 复制代码
 let fileHandles;
 const options = {
  multiple: true,
 };

 document.querySelector(".pick-file-button").onclick = async () => {
  fileHandles = await window.showOpenFilePicker(options);

  const allContent = await Promise.all(
    fileHandles.map(async (fileHandle) => {
      const file = await fileHandle.getFile();
      const content = await file.text();
      return content;
    })
  );

  console.log(allContent);
 };

写入文件

文件系统访问 API 也允许向文件写入内容。

写入新文件

写入新文件实现!

dart 复制代码
 document.querySelector(".save-file-button").onclick = async () => {
  const options = {
    types: [
      {
        description: "测试文件",
        accept: {
          "text/plain": [".txt"],
        },
      },
    ],
  };

  const handle = await window.showSaveFilePicker(options);
  const writable = await handle.createWritable();

  await writable.write("Hello World");
  await writable.close();

  return handle;
 };

假设我们有第二个 class 为 save-file-button 的按钮,点击时,通过 showSaveFilePicker() 方法打开文件选择器,并在 options 对象中指明要保存的文件类型,这里是 .txt 文件。

调用这个方法同样会返回一个 FileSystemFileHandle 对象,就像第一部分一样。在这个对象上调用 createWritable() 方法会返回一个 FileSystemWritableFileStream 对象。然后我们可以通过 write() 方法往这个流里写入内容。

最后,需要调用 close() 方法来关闭文件,完成内容写入。

例如,如果要写入 HTML 代码到文件,只需要在 options 对象里将内容类型设为 "text/html" , 调用 write () 方法传入 HTML 内容即可。

编辑现有文件

如果要导入一个文件并用文件系统访问 API 编辑,示例代码如下:

ini 复制代码
 let fileHandle;

 document.querySelector(".pick-file-button").onclick = async () => {
  [fileHandle] = await window.showOpenFilePicker();

  const file = await fileHandle.getFile();
  const writable = await fileHandle.createWritable();

  await writable.write("添加新的内容");
  await writable.close();
 };

如果你已经阅读过前面的内容,可能会注意到我们首先通过 showOpenFilePicker()getFile() 方法读取一个文件,然后用 createWritable()write()close() 方法写入同一个文件。

如果导入的文件已经包含一些内容,这个代码会用传给 write() 方法的新内容替换原有的文件内容。

其他功能

文件系统访问 API 还可以列出目录中的文件,以及删除文件和目录。

读取目录

代码示例:

dart 复制代码
 document.querySelector(".read-dir-button").onclick = async () => {
  const directoryHandle = await window.showDirectoryPicker();

  for await (const entry of directoryHandle.values()) {
    console.log(entry.kind, entry.name);
  }
 };

添加一个 class 为 .read-dir-button 的按钮,点击时调用 showDirectoryPicker () 方法会打开文件选择器,选择计算机上的一个目录后,这段代码会列出该目录中的文件。

删除文件

可以用以下代码删除一个目录中的文件:

dart 复制代码
 document.querySelector(".pick-file-button").onclick = async () => {
  const [fileHandle] = await window.showOpenFilePicker();
  await fileHandle.remove();
 };

如果您想删除一个文件夹,只需对上述代码示例做一个小修改:

dart 复制代码
 document.querySelector(".pick-file-button").onclick = async () => {
  const directoryHandle = await window.showDirectoryPicker();
  await directoryHandle.remove();
 };

最后,如果您在选择文件夹时想要删除一个特定文件,可以这样写:

dart 复制代码
 // 删除所选文件夹中名为data.txt的文件
 document.querySelector(".pick-folder-button").onclick = async () => {
    const directoryHandle = await window.showDirectoryPicker();
    await directoryHandle.removeEntry("data.txt");
 };

如果想删除整个文件夹:

dart 复制代码
 // 递归删除名为"data"的文件夹
 document.querySelector(".pick-folder-button").onclick = async () => {
    const directoryHandle = await window.showDirectoryPicker();
    await directoryHandle.removeEntry('data', { recursive: true });
 };

File System Access API 浏览器支持情况

目前,IE 和 Firefox 浏览器似乎都不支持 File System Access API。不过,存在一个名为 browser-fs-access的腻子 (polyfill)。

总结

本文主要介绍了File System Access API的基本使用,包括如何获取文件和目录,以及如何操作文件和目录。

相关推荐
乐多_L35 分钟前
使用vue3框架vue-next-admin导出表格excel(带图片)
前端·javascript·vue.js
南望无一1 小时前
React Native 0.70.x如何从本地安卓源码(ReactAndroid)构建
前端·react native
Mike_188702783511 小时前
1688代采下单API接口使用指南:实现商品采集与自动化下单
前端·python·自动化
鲨鱼辣椒️面1 小时前
HTML视口动画
前端·html
一小路一1 小时前
Go Web 开发基础:从入门到实战
服务器·前端·后端·面试·golang
堇舟1 小时前
HTML第一节
前端·html
纯粹要努力1 小时前
前端跨域问题及解决方案
前端·javascript·面试
小刘不知道叫啥1 小时前
React源码揭秘 | 启动入口
前端·react.js·前端框架
kidding7231 小时前
uniapp引入uview组件库(可以引用多个组件)
前端·前端框架·uni-app·uview
合法的咸鱼1 小时前
uniapp 使用unplugin-auto-import 后, vue文件报红问题
前端·vue.js·uni-app