---
title: "fs.readDir"
description: "列出虚拟目录的直接子项并返回文件或目录元数据。"
---


> 列出虚拟目录的直接子项，并返回可继续交给文件 API 使用的虚拟路径。

## 签名

```ts
KSM.fs.readDir(args: {
  path: string;
}): Promise<{ entries: KSMDirectoryEntry[] }>
```

命名导出调用形式相同：`fs.readDir({ path })`。

## 平台与权限

| Windows | Android |权限 |
| --- | --- | --- |
|支持 |支持 | `fs.read` |

## 参数

|参数 |类型 |必填 |说明 |
| --- | --- | --- | --- |
| `path` | `string` |是 |可读目录的 `app://` 虚拟路径 |

目录根可以使用 `app://data`、`app://cache`、`app://tmp`、`app://res` 或
`app://assets`，也可以带末尾 `/`。`app://picked` 不是目录，传入 picked 句柄会被拒绝。

## 返回值

`entries` 是当前目录的直接子项数组，不递归展开。每项结构如下：

|字段 |类型 |说明 |
| --- | --- | --- |
| `name` | `string` |目录项名称，不包含父路径 |
| `path` | `string` |可直接传给 `readText`、`stat` 等方法的虚拟路径 |
| `kind` | `'file' \| 'directory'` |普通文件或目录 |
| `size` | `number` |文件字节数；目录固定为 `0` |
| `modifiedAt` | `number \| null` |Unix 毫秒；宿主无法提供时为 `null` |

结果按 `name` 升序排列。目录为空时返回 `{ entries: [] }`，不是错误。

## 行为

- `app://data`、`app://cache`、`app://tmp` 读取宿主可写沙箱。
- `app://res` 和 `app://assets` 读取打包资源；资源的 `modifiedAt` 可能为 `null`。
- `app://picked/<id>` 只表示单个用户文件，不能作为目录读取。
- 符号链接不会被跟随，也不会出现在结果中。
- 只返回直接子项，不保证递归遍历或隐藏文件过滤。

## 示例

```ts
const { entries } = await KSM.fs.readDir({
  path: 'app://data'
});

for (const entry of entries) {
  console.info(entry.name, entry.kind, entry.size);
}

const firstFile = entries.find((entry) => entry.kind === 'file');
if (firstFile) {
  const metadata = await KSM.fs.stat({ path: firstFile.path });
  console.info(metadata.modifiedAt);
}
```

## 错误

|错误 |场景 |
| --- | --- |
|普通 `TypeError` |路径未通过前端目录守卫，或使用了 `app://picked` |
| `INVALID_ARGS` |目标存在但不是目录 |
| `PERMISSION_DENIED` |路径越出可读沙箱，或权限不可用 |
| `NOT_FOUND` |目录不存在 |
| `IO_ERROR` |目录存在但无法枚举或读取元数据 |
| `NOT_SUPPORTED` |对应文件或资源服务未配置 |
| `TIMEOUT` |宿主未在默认时间内响应 |

## 相关

- [fs.mkdir](/docs/kasumi/api/fs/mkdir)
- [fs.stat](/docs/kasumi/api/fs/stat)
- [fs 模块](/docs/kasumi/api/fs)
