Filer文件读写完全指南:writeFile/readFile/open/write 8个实例一次掌握

发布时间:2026/8/24 16:24:59
Filer文件读写完全指南:writeFile/readFile/open/write 8个实例一次掌握 Filer文件读写完全指南writeFile/readFile/open/write 8个实例一次掌握【免费下载链接】filerNode-like file system for browsers项目地址: https://gitcode.com/gh_mirrors/fi/filerFiler 是一个运行在浏览器中的 Node.js 风格文件系统Node-like file system for browsers它让你用fs.writeFile、fs.readFile、fs.open、fs.write这套熟悉的 API在网页里创建、读写、管理文件数据默认持久化到 IndexedDB。本指南通过 8 个由浅入深的实例带你在 30 分钟内掌握 Filer 的文件读写核心技能。 一张表看懂本指南的 8 个实例序号实例核心 API适用场景1快速写入一个文件fs.writeFile保存文本、配置数据2以文本方式读取文件fs.readFile读取 UTF-8 文本3以二进制 Buffer 读取文件fs.readFile读取图片、音频等二进制4打开文件获得文件描述符fs.open读写之前先“打开”5向文件描述符精确写入fs.write指定位置写数据6从文件描述符精确读取fs.read指定位置读数据7在文件末尾追加内容fs.appendFile写日志8用 Promise 优雅地读写fs.promises现代 async/await 风格 快速上手安装与加载 FilerFiler 有两种常见获取方式# 方式一npm 安装推荐 npm install filer # 方式二克隆源码 git clone https://gitcode.com/gh_mirrors/fi/filer加载方式与 node 模块几乎一致从 src/index.js 可以确认Filer 对外暴露了FileSystem、Buffer、path、Shell等模块并提供一个开箱即用的fs实例const { fs, path } require(filer); // fs 就是一个默认基于 IndexedDB 的文件系统实例 小技巧Filer.fs是懒加载的单例见 src/index.js 中的Object.defineProperty(Filer, fs, ...)每次访问拿到的都是同一个文件系统直接用它即可完成本指南全部实例。 实例 1用 writeFile 快速写入文件writeFile是最常用的写入 API文件不存在就创建已存在就覆盖。数据可以是字符串默认按 UTF-8 编码或 Buffer。const { fs } require(filer); fs.mkdir(/docs, (err) { if (err) return console.error(创建目录失败, err); const filename /docs/hello.txt; fs.writeFile(filename, Hello Filer!\n, (err) { if (err) return console.error(写入失败, err); console.log(已写入, filename); }); });参数要点对应 src/filesystem/implementation.js#L1935 的writeFile实现第一个参数是绝对路径Filer 的 FileSystem 没有“当前目录”概念/即根目录第三个参数可选可传utf8或{ encoding, flag }对象回调的第一个参数永远是err必须检查 实例 2用 readFile 以文本方式读取指定utf8编码data就是普通的 JS 字符串fs.readFile(/docs/hello.txt, utf8, (err, data) { if (err) return console.error(读取失败, err); console.log(data); // - Hello Filer!\n }); 实例 3用 readFile 读取二进制数据Buffer不指定编码时返回的是Buffer浏览器中是一个增强版Uint8Array适合保存图片、ZIP 等二进制文件fs.readFile(/data/blob.bin, (err, data) { if (err) return console.error(读取失败, err); console.log(data.length); // 字节数 console.log(data.slice(0, 4)); // 前 4 个字节 });写入二进制同理把 Buffer 直接传给writeFile即可编码参数会被自动忽略const buf require(buffer).Buffer.from([1, 2, 3, 4, 5]); fs.writeFile(/data/blob.bin, buf, (err) { /* ... */ }); 实例 4用 open 打开文件需要更精细控制时先用fs.open(path, flags, callback)拿到文件描述符fd。flags的取值flags行为r只读文件不存在会报错r读写文件不存在会报错w只写不存在则创建存在则清空w读写不存在则创建存在则清空a追加写不存在则创建a追加读写不存在则创建fs.open(/docs/notes.txt, w, (err, fd) { if (err) return console.error(打开失败, err); console.log(打开成功fd , fd); // 拿到 fd 之后就可以用 write / fstat / close 了 });⚠️ 常见坑w模式会截断已有文件想保留原内容请用a追加或r。✍️ 实例 5用 write 向文件描述符写入数据签名是fs.write(fd, buffer, offset, length, position, callback)前四个参数描述“写 buffer 的哪一段”position决定“写到文件里的哪个位置”传null表示写到当前位置。回调收到(err, nbytes)nbytes是实际写入的字节数const buf require(buffer).Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]); fs.open(/data/nums.bin, w, (err, fd) { if (err) return console.error(err); // 从 buffer 第 0 字节开始写 8 个字节写到文件位置 0 fs.write(fd, buf, 0, buf.length, 0, (err, nbytes) { if (err) return console.error(err); console.log(写入了, nbytes, 字节); // - 8 fs.close(fd, () console.log(已关闭文件)); }); });实现细节可在 src/filesystem/implementation.js#L1918 的write函数中查看当前版本会一次性写入整个 buffer并返回实际写入字节数。 实例 6用 read 从文件描述符读取数据与write完全对称fs.read(fd, buffer, offset, length, position, callback)回调收到(err, nbytes)。通常先用fs.fstat(fd, ...)拿到文件大小再分配等大的 bufferfs.open(/data/nums.bin, r, (err, fd) { if (err) return console.error(err); fs.fstat(fd, (err, stats) { if (err) return console.error(err); const buf require(buffer).Buffer.alloc(stats.size); fs.read(fd, buf, 0, buf.length, 0, (err, nbytes) { if (err) return console.error(err); console.log(读回 ${nbytes} 字节, buf.toString(latin1)); fs.close(fd); }); }); }); 记忆口诀open → read/write → close三者是一套“打开—操作—关闭”的完整流程忘了close会一直占用文件描述符。 实例 7用 appendFile 追加日志内容写日志是最典型的追加场景。appendFile会保留原有内容把新数据接到文件末尾fs.appendFile(/logs/app.log, [${new Date().toISOString()}] 启动完成\n, (err) { if (err) return console.error(err); }); // 二进制追加同样支持 const tail require(buffer).Buffer.from([0x0A]); fs.appendFile(/data/nums.bin, tail, (err) { /* ... */ });与writeFile的关键区别writeFile覆盖整个文件appendFile只增加、不覆盖——写日志、写事件流时务必选对。⚡ 实例 8用 Promises 写法现代风格Filer 的FileSystem和Shell都提供promises属性方法名与回调版完全一致只是改为返回 Promise可以直接配合async/await使用const Filer require(filer); async function main() { const fs new Filer.FileSystem().promises; await fs.writeFile(/todo.txt, 买牛奶\n写代码\n); const content await fs.readFile(/todo.txt, utf8); const stats await fs.stat(/todo.txt); console.log(content); console.log(文件大小, stats.size, 字节); } main().catch(console.error);提示回调风格与 Promise 风格可以混用fs.promises只影响你从哪个入口取方法底层是同一套实现。 选择存储后端IndexedDB 还是 MemoryFiler 的读写能力由底层“存储 Provider”支撑见 src/providers/index.js目前内置两种IndexedDB默认数据持久化在浏览器本地关闭页面后再次打开仍可读回适合生产环境Memory纯内存速度更快、零配置但页面刷新即丢失适合单元测试或临时数据const Filer require(filer); // 使用 Memory 后端适合测试 const testFs new Filer.FileSystem({ provider: new Filer.FileSystem.providers.Memory() }); // 强制格式化清空一个文件系统 const freshFs new Filer.FileSystem({ name: my-app, flags: [FORMAT] }); 常见错误速查Filer 的错误对象与 node 保持一致支持err.code与err.errno判断错误定义见 src/errors.js错误码含义解决办法ENOENT路径不存在先fs.mkdir创建目录或检查拼写EEXIST路径已存在改用覆盖写入w或删除后重建EISDIR/ENOTDIR把目录当文件或反之用fs.stat先确认节点类型EBADF文件描述符无效确认fd来自未close的fs.openfs.readFile(/not-exist.txt, utf8, (err, data) { if (err) { if (err.code ENOENT) return console.log(文件不存在先创建); throw err; } });✅ 总结如何选择读写方式一次性写整个文件→fs.writeFile最简单一次性读整个文件→fs.readFile记得按需指定utf8追加内容→fs.appendFile需要在文件中间读/写、或复用已打开的文件→fs.openfs.read/fs.writefs.close追求代码简洁→ 直接用fs.promises的 async/await 版本Filer 的 API 设计几乎 1:1 复刻 node.js 的fs模块唯一要记住的差异是没有同步方法如readFileSync、路径必须绝对路径。把这篇指南的 8 个实例跑通你就已经能在浏览器里自如地构建离线应用、本地缓存系统和纯前端文档工具了。延伸阅读源码路径速查入口与fs单例src/index.js全部文件系统方法实现src/filesystem/implementation.jsopen在 L1707、readFile在 L1863、writeFile在 L1935 附近存储 Providersrc/providers/index.jswebpack 插件把 node 的fs/path直接替换为 Filersrc/webpack-plugin/index.js完整测试用例最好的实战教材tests/spec/fs.writeFile-readFile.spec.js、tests/spec/fs.open.spec.js【免费下载链接】filerNode-like file system for browsers项目地址: https://gitcode.com/gh_mirrors/fi/filer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考