ITADN
zen-fs/core
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈

ZenFS

ZenFS 是一个跨平台库,用于模拟 Node.js 文件系统 API。 它通过一套后端系统工作,ZenFS 使用这些后端来存储和检索数据。 ZenFS 还可以与其他工具集成。

后端

ZenFS 是模块化的,易于扩展。核心包含一些内置后端:

  • InMemory: 在内存中存储文件。当运行时结束时(例如用户离开网页或 Node 进程退出)会被清除
  • CopyOnWrite: 使用可读和可写文件系统,并采用 写时复制
  • Fetch: 通过 fetch API 使用 HTTP 下载文件
  • Port: 通过类似 MessagePort 的接口与远程交互(例如 worker)
  • Passthrough: 使用现有的 node:fs 接口与 ZenFS 配合
  • SingleBuffer: 包含在单个缓冲区中的后端。可以使用 SharedArrayBuffer 进行同步多线程操作

ZenFS 支持许多其他后端。 许多作为单独的软件包在 @zenfs 下提供。 可以通过扩展 FileSystem 类并提供一个 Backend 对象,由单独的库定义更多后端。

你可以在 NPM 上找到所有可用的软件包。以下是其中一些软件包包含的后端列表:

  • @zenfs/archives: Zip, Iso
  • @zenfs/cloud: Dropbox, GoogleDrive, S3Bucket
  • @zenfs/dom: WebAccess (Web 文件系统访问 API/OPFS), IndexedDB, WebStorage (localStorage/sessionStorage), XML (DOM 元素)
  • @zenfs/emscripten: Emscripten 以及 Emscripten 文件系统 API 的插件

作为额外的好处,所有 ZenFS 后端都支持同步操作。 此外,核心中包含的所有后端都是跨平台的。

有关更多信息,请参阅 docs

安装

npm install @zenfs/core

如果你正在使用 ZenFS,尤其是用于大型项目,请考虑支持该项目。 数千小时已投入其开发。 你的财务支持将极大地推动 ZenFS 及其社区的改进。

用法

import { fs } from '@zenfs/core'; // You can also use the default export

fs.writeFileSync('/test.txt', 'You can do this anywhere, including browsers!');

const contents = fs.readFileSync('/test.txt', 'utf-8');
console.log(contents);

使用不同和/或多个后端

默认情况下,会创建一个 InMemory 后端,并挂载到 /

您可以配置 ZenFS 使用不同的后端并挂载多个后端。强烈建议使用 configure 函数来实现。

您可以通过向 configure 传递一个对象来使用多个后端,该对象将路径映射到文件系统。

以下示例将 zip 文件挂载到 /zip,将内存存储挂载到 /tmp,将 IndexedDB 挂载到 /home。请注意,/ 具有默认的内存后端。

import { configure, InMemory } from '@zenfs/core';
import { IndexedDB } from '@zenfs/dom';
import { Zip } from '@zenfs/archives';

const res = await fetch('mydata.zip');

await configure({
	mounts: {
		'/mnt/zip': { backend: Zip, data: await res.arrayBuffer() },
		'/tmp': InMemory,
		'/home': IndexedDB,
	},
});

请注意,虽然您不必使用 mounts 的键的绝对路径,但这样做是一个好习惯。

[!TIP] 在配置挂载点时,您可以传入

  1. 一个 Backend 对象,如果后端没有必需的选项
  2. 一个包含后端接受的选项和一个 backend 属性的对象,该属性是一个 Backend 对象
  3. 一个 FileSystem 实例

以下是一个将 @zenfs/domWebStorage 后端挂载到 / 的示例:

import { configureSingle, fs } from '@zenfs/core';
import { WebStorage } from '@zenfs/dom';

await configureSingle({ backend: WebStorage });

if (!fs.existsSync('/test.txt')) {
	fs.writeFileSync('/test.txt', 'This will persist across reloads!');
}

const contents = fs.readFileSync('/test.txt', 'utf-8');
console.log(contents);

FS Promises

FS promises API 以 promises 的形式暴露。

import { configureSingle } from '@zenfs/core';
import { exists, writeFile } from '@zenfs/core/promises';
import { IndexedDB } from '@zenfs/dom';

await configureSingle({ backend: IndexedDB });

const exists = await exists('/myfile.txt');
if (!exists) {
	await writeFile('/myfile.txt', 'Lots of persistent data');
}

[!NOTE] 你可以使用以下方式导入 promises API:

  1. 来自 @zenfs/core/promises 的导出
  2. 来自 @zenfs/corepromises 导出
  3. 来自 @zenfs/core 的已导出 fs 上的 fs.promises

挂载与卸载,创建后端

如果你希望在不使用 configure 的情况下创建后端(例如在运行时执行某些动态操作),你可以通过导入后端并调用 resolveMountConfig 来实现。

然后,你可以使用 mountumount 来挂载和卸载后端实例。

import { configure, resolveMountConfig, InMemory } from '@zenfs/core';
import { IndexedDB } from '@zenfs/dom';
import { Zip } from '@zenfs/archives';

await configure({
	mounts: {
		'/tmp': InMemory,
		'/home': IndexedDB,
	},
});

fs.mkdirSync('/mnt/zip', { recursive: true });

const res = await fetch('mydata.zip');
const zipfs = await resolveMountConfig({ backend: Zip, data: await res.arrayBuffer() });
fs.mount('/mnt/zip', zipfs);

// do stuff with the mounted zip

fs.umount('/mnt/zip'); // finished using the zip

[!CAUTION] 后端实例遵循 内部 API。除非您正在扩展后端,否则不应使用后端的方法。

设备与设备文件

ZenFS 包含对设备文件的支持。这些设计旨在遵循 Linux 的设备文件行为,以保持一致性和易用性。请参阅 Devices and Device Drivers 文档以获取更多信息。

node:* 仿真

ZenFS 还包含对其他一些 node: 模块的仿真,出于各种原因,可从 @zenfs/core/<name> 导入:

  • node:path
  • node:readline

例如:

import * as path from '@zenfs/core/path';

打包

ZenFS 导出了 Node 的 fs 模块的替代方案,因此您可以使用默认导出将其用于您选择的打包器。

[!IMPORTANT] 参见 COPYING.md

赞助商

衷心感谢 deco.cx 赞助 ZenFS 并帮助实现这一切。

联系与支持

您可以通过 Discord 或发送邮件至 jp@zenfs.dev 与我们联系