---
title: "fs"
description: "在 Kasumi 虚拟文件系统中读写文本、检查文件存在性并删除可写文件。"
---


> 在 Kasumi 虚拟文件系统中读写文本、检查文件存在性并删除可写文件。

## 模块边界

`fs` 只接受 `app://` 虚拟路径，不暴露宿主真实路径、`content://` URI 或绕过协议的
第三个文件 API。实现入口是 `frontend/src/api/fs.ts` 和
`frontend/src/api/guards.ts`。

## 方法索引

|方法 |权限 |返回值 |
| --- | --- | --- |
| [readText](/docs/kasumi/api/fs/read-text) | `fs.read` | `string \| { file }` |
| [writeText](/docs/kasumi/api/fs/write-text) | `fs.write` | `{ written: true }` |
| [exists](/docs/kasumi/api/fs/exists) | `fs.read` | `{ exists: boolean }` |
| [remove](/docs/kasumi/api/fs/remove) | `fs.remove` | `{ removed: boolean }` |

## 虚拟根

|路径 |用途 |读取 |写入 /删除 |
| --- | --- | --- | --- |
| `app://data/**` |应用私有数据 |是 |是 |
| `app://cache/**` |缓存 |是 |是 |
| `app://tmp/**` |临时文件 |是 |是 |
| `app://picked/**` |用户选择的文件 |是 |是 |
| `app://res/**` |打包资源 |是 |否 |
| `app://assets/**` |前端构建资源 |是 |否 |

`app://picked/<id>` 只接受一个文件 token，不能继续带子路径。文件选择器返回的句柄
才能映射到用户文件，业务代码不得自行拼接 token。

## 路径守卫

前端会在发送请求前拒绝以下输入：

- 空字节、`..`、`~`。
- 非 `app://data|cache|tmp|picked|res|assets` 根。
- 根后相对路径为空。
- 相对路径含 `:`、反斜杠或以 `/` 开头。
- 写入或删除只读根。
- `app://picked/<id>` 中出现额外 `/`。

这些情况抛普通 `TypeError`，不是 `INVALID_ARGS` 或 `PERMISSION_DENIED`。
绕过前端封装直接调用 `KSM.invoke()` 时，仍由宿主执行同样的路径拒绝。

## 大文本

单条消息上限是 64 KiB。`readText` 读取的内容超过 64 KiB 时返回：

```ts
{ file: 'app://tmp/read-1.txt' }
```

句柄指向临时文件，不是原始文件路径。再次读取同一个临时句柄仍返回该句柄，
不会无限复制。单文件读取上限是 16 MiB。

## 示例

```ts
import { fs } from '@kasumi/bridge';

await fs.writeText({
  path: 'app://data/config.json',
  content: '{"ready":true}'
});

const result = await fs.readText({
  path: 'app://data/config.json'
});

if (typeof result === 'string') {
  console.info(result);
} else {
  console.info(`大文本句柄: ${result.file}`);
}
```

## 排查路径

1. 确认路径以已注册的虚拟根开头，并包含非空相对路径。
2. 确认写入目标属于 `data`、`cache`、`tmp` 或有效的 `picked` 句柄。
3. 确认前端抛出的错误类型，`TypeError` 通常是路径守卫直接拒绝。
4. 确认读取结果不是 `{ file }`；大文本需要按句柄继续处理。
5. 确认单文件不超过 16 MiB，单条消息不超过 64 KiB。

## 相关

- [errors](/docs/kasumi/api/errors)
- [dialog.openFile](/docs/kasumi/api/dialog/open-file)