# fs-async **Repository Path**: nodets/fs-async ## Basic Information - **Project Name**: fs-async - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-06 - **Last Updated**: 2025-10-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # fs-async 轻量级异步文件操作工具,基于 Node.js 原生 `fs/promises` 实现,**无第三方依赖**,支持文件读写、目录管理、路径匹配等核心场景,提供清晰的 TypeScript 类型提示,简化日常异步文件处理流程。 ## 特性 - 🚀 **纯异步非阻塞**:基于 `fs/promises` 开发,避免阻塞事件循环,适配 Node.js 异步生态 - 📦 **零额外依赖**:移除 `glob` 等第三方库,仅依赖 Node.js 原生 API,减少项目体积 - 🔧 **核心功能全覆盖**:文件读写、JSON 处理、目录管理、路径匹配、哈希计算等常用操作 - ✅ **TypeScript 原生支持**:完整类型定义,支持 IDE 自动补全和类型校验,减少运行时错误 - 🖥️ **跨平台兼容**:统一处理 Windows/macOS/Linux 路径分隔符,避免跨平台路径问题 ## 安装 ```bash # 安装核心包 npm install fs-async --save # 低版本 Node.js(<16)如需 TypeScript 类型支持,需手动安装 @types/node npm install @types/node --save-dev ``` ## 快速开始 ### 基础示例(ES Module) ```typescript // 导入工具(默认导出为 fs 对象,与原生 fs 命名习惯一致) import fs from 'fs-async'; async function fileOpsDemo() { try { // 1. 写入文件(自动创建不存在的父目录) await fs.write('./data/log.txt', '2024-01-01: 系统启动成功'); // 2. 读取文件(默认编码 utf-8) const logContent = await fs.read('./data/log.txt'); console.log('日志内容:', logContent); // 输出:2024-01-01: 系统启动成功 // 3. 写入 JSON 文件(自动格式化,缩进 2 空格) await fs.writeJSON('./data/config.json', { theme: 'dark', timeout: 3000 }); // 4. 读取 JSON 文件(自动解析) const config = await fs.readJSON('./data/config.json'); console.log('配置主题:', config.theme); // 输出:dark // 5. 复制目录(强制覆盖已存在的目标目录) await fs.copy('./data', './data-backup', { force: true }); // 6. 路径匹配(查找所有 .json 文件) const jsonFiles = await fs.expand('**/*.json', { onlyFiles: true }); console.log('JSON 文件列表:', jsonFiles); // 输出:[ 'data/config.json', 'data-backup/config.json' ] } catch (err: any) { console.error('文件操作失败:', err.message); } } fileOpsDemo(); ``` ### CommonJS 示例 ```javascript // 导入工具 const fs = require('fs-async'); async function dirOpsDemo() { try { // 创建嵌套目录 await fs.mkdir('./temp/docs'); // 检查路径是否为目录 const isDir = await fs.isDir('./temp/docs'); console.log('./temp/docs 是否为目录:', isDir); // 输出:true // 清空目录(保留目录本身,删除内容) await fs.emptyDir('./temp/docs'); // 删除目录(递归删除整个目录) await fs.remove('./temp'); } catch (err) { console.error('目录操作失败:', err.message); } } dirOpsDemo(); ``` ## API 文档 所有方法均返回 `Promise`,支持 `async/await` 调用,以下是核心 API 说明: ### 1. 文件操作 | 方法 | 说明 | 参数 | 返回值 | |------|------|------|--------| | `fs.write(file, content, [options])` | 写入文件(自动创建父目录) | `file`: 目标文件路径
`content`: 写入内容(string/Buffer)
`options`: 可选,`fs.WriteFileOptions`(含 `encoding`/`flag` 等) | `Promise` | | `fs.read(file, [options])` | 读取文件 | `file`: 文件路径
`options`: 可选,含 `encoding`(默认 `utf-8`)/`flag` | `Promise` | | `fs.readJSON(file, [options])` | 读取 JSON 文件并解析 | `file`: JSON 文件路径
`options`: 可选,同 `fs.read` 的 `options` | `Promise`(解析后的 JSON 对象) | | `fs.writeJSON(file, data, [spaces])` | 写入 JSON 文件(自动格式化) | `file`: 目标文件路径
`data`: 要序列化的 JSON 数据
`spaces`: 可选,缩进空格数(默认 2) | `Promise` | | `fs.appendFile(file, content, [options])` | 向文件追加内容 | 参数同 `fs.write` | `Promise` | | `fs.copy(from, to, [options])` | 复制文件/目录 | `from`: 源路径
`to`: 目标路径
`options`: 可选,`{ force?: boolean; preserveTimestamps?: boolean }`(`force` 强制覆盖,默认 false;`preserveTimestamps` 保留时间戳,默认 false) | `Promise` | | `fs.move(from, to, [options])` | 移动/重命名文件/目录(跨设备自动降级为复制+删除) | `from`: 源路径
`to`: 目标路径
`options`: 可选,`{ force?: boolean }`(强制覆盖,默认 false) | `Promise` | | `fs.remove(path)` | 删除文件/目录(递归删除,等同于 `rm -rf`) | `path`: 要删除的路径 | `Promise` | | `fs.hashFile(file, [algorithm])` | 计算文件哈希值 | `file`: 文件路径
`algorithm`: 可选,哈希算法(默认 `sha256`,支持 `md5`/`sha1` 等) | `Promise`(十六进制哈希字符串) | ### 2. 目录操作 | 方法 | 说明 | 参数 | 返回值 | |------|------|------|--------| | `fs.mkdir(dirPath)` | 创建目录(递归创建,等同于 `mkdir -p`) | `dirPath`: 目标目录路径 | `Promise` | | `fs.readDir(dir, [options])` | 读取目录内容 | `dir`: 目录路径
`options`: 可选,`{ withFileTypes?: boolean }`(`withFileTypes` 为 true 时返回 `fs.Dirent` 对象数组,否则返回文件名数组) | `Promise` | | `fs.emptyDir(dir)` | 清空目录(保留目录本身,删除所有子内容) | `dir`: 目录路径 | `Promise` | | `fs.isDir(path)` | 判断路径是否为目录 | `path`: 路径 | `Promise` | | `fs.isFile(path)` | 判断路径是否为文件 | `path`: 路径 | `Promise` | | `fs.exists(...paths)` | 判断路径是否存在(支持多参数拼接路径,如 `fs.exists('src', 'utils', 'file.ts')`) | `paths`: 路径片段(可多个) | `Promise` | ### 3. 路径工具 | 方法 | 说明 | 参数 | 返回值 | |------|------|------|--------| | `fs.expand(patterns, [options])` | 路径匹配(支持 `*`/`**` 模式,替代 `glob`) | `patterns`: 匹配模式(string 或 string 数组,如 `'**/*.ts'`)
`options`: 可选,`{ cwd?: string; dot?: boolean; onlyFiles?: boolean; onlyDirs?: boolean }`(`cwd` 工作目录,默认当前目录;`dot` 匹配隐藏文件,默认 false;`onlyFiles`/`onlyDirs` 仅匹配文件/目录) | `Promise`(匹配的路径数组) | | `fs.isPathAbsolute(path)` | 判断路径是否为绝对路径 | `path`: 路径 | `Promise` | | `fs.doesPathContain(ancestor, ...paths)` | 判断祖先路径是否包含所有子路径 | `ancestor`: 祖先路径
`paths`: 子路径(可多个) | `Promise` | | `fs.createSymlink(target, linkPath, [options])` | 创建符号链接 | `target`: 链接指向的目标路径
`linkPath`: 链接文件路径
`options`: 可选,`{ type?: 'file' | 'dir' | 'junction' }`(链接类型,默认 `file`) | `Promise` | | `fs.realpath(path)` | 获取符号链接指向的真实路径 | `path`: 符号链接路径 | `Promise` | ## 错误处理 所有方法抛出的错误均包含清晰的描述信息,可通过 `try/catch` 捕获并处理: ```typescript try { await fs.read('./nonexistent.txt'); } catch (err: any) { console.error('错误类型:', err.name); // 输出:Error console.error('错误信息:', err.message); // 输出:文件不存在:./nonexistent.txt } ``` 常见错误场景: - 路径不存在:`文件不存在:xxx`/`目录不存在:xxx` - 路径已存在:`目标已存在(设 force: true 覆盖):xxx` - 类型不匹配:`路径是目录:xxx`/`路径是文件:xxx` ## 注意事项 1. **`fs.remove` 风险提示**:`fs.remove` 等同于 `rm -rf`,会递归删除目录所有内容,请谨慎使用,避免误删重要文件。 2. **跨设备移动**:`fs.move` 在跨设备(如 C 盘到 D 盘)时会自动降级为“复制+删除”,确保操作成功。 3. **路径匹配能力**:`fs.expand` 支持基础的 `*`(匹配单层任意字符)和 `**`(匹配多层目录)模式,复杂场景可自行扩展。 ## 版本兼容 - 支持 Node.js 14+(推荐 Node.js 16+,原生支持完整的 `fs/promises` API) - TypeScript 4.5+(如需类型校验)