如何在Nodejs中使用模块fs文件系统
概述
node 的fs文档密密麻麻的 api 非常多,毕竟全面支持对文件系统的操作。文档组织的很好,操作基本分为文件操作、目录操作、文件信息、流这个大方面,编程方式也支持同步、异步和 Promise。
本文记录了几个文档中没详细描写的问题,可以更好地串联fs文档思路
- 文件描述符
- 同步、异步与 Promise
- 目录与目录项
- 文件信息
- stream
文件描述符
文件描述符是一个非负整数。它是一个索引值,操作系统可以根据它来找到对应的文件。
在 fs 的很多底层 api 中,需要用到文件描述符。在文档中,描述符通常用fd来代表。例如fs.read(fd, buffer, offset, length, position, callback)。与这个 api 相对应的是fs.readFile(path[, options], callback)。
因为操作系统对文件描述符的数量有限制,在结束文件操作后,别忘记 close:
const fs = require("fs"); fs.open("./db.json", "r", (err, fd) => { if (err) throw err; // 文件操作... // 完成操作后,关闭文件 fs.close(fd, err => { if (err) throw err; }); });
同步、异步与 Promise
所有文件系统的 api 都有同步和异步两种形式。
同步写法
不推荐使用同步 api,会阻塞线程。
try { const buf = fs.readFileSync("./package.json"); console.log(buf.toString("utf8")); } catch (error) { console.log(error.message); }
异步写法
异步写法写起来容易进入回调地狱。
fs.readFile("./package.json", (err, data) => { if (err) throw err; console.log(data.toString("utf8")); });
(推荐)Promise 写法
在 node v12 之前,需要自己借助 promise 封装
function readFilePromise(path, encoding = "utf8") { const promise = new Promise((resolve, reject) => { fs.readFile(path, (err, data) => { if (err) return reject(err); return resolve(data.toString(encoding)); }); }); return promise; } readFilePromise("./package.json").then(res => console.log(res));
在 node v12 中,引入了 fs Promise api。它们返回 Promise 对象而不是使用回调。 API 可通过require('fs').promises访问。如此一来,开发成本更低了。
const fsPromises = require("fs").promises; fsPromises .readFile("./package.json", { encoding: "utf8", flag: "r" }) .then(console.log) .catch(console.error);
目录与目录项
fs.Dir 类封装了和文件目录相关的操作
fs.Dirent 类封装了目录项的相关操作。例如判断设备类型(字符、块、FIFO 等)。
它们之间的关系,通过代码展示
const fsPromises = require("fs").promises; async function main() { const dir = await fsPromises.opendir("."); let dirent = null; while ((dirent = await dir.read()) !== null) { console.log(dirent.name); } } main();
文件信息
fs.Stats 类封装了文件信息相关的操作。它在fs.stat()的回调函数中返回。
fs.stat("./package.json", (err, stats) => { if (err) throw err; console.log(stats); });
注意,关于检查文件是否存在
- 不建议在调用 fs.open()、 fs.readFile() 或 fs.writeFile() 之前使用 fs.stat() 检查文件是否存在。而是应该直接打开、读取或写入文件,如果文件不可用则处理引发的错误。
- 要检查文件是否存在但随后并不对其进行操作,则建议使用 fs.aess()
ReadStream 与 WriteStream
在 nodejs 中,stream 是个非常重要的库。很多库的 api 都是基于 stream 来封装的。例如狼蚁网站SEO优化要说的 fs 中的 ReadStream 和 WriteStream。
fs 本身提供了 readFile 和 writeFile,它们好用的代价就是性能有问题,会将内容一次全部载入内存。对于几 GB 的大文件,显然会有问题。
那么针对大文件的解决方案自然是一点点读出来。这就需要用到 stream 了。以 readStream 为例,代码如下
const rs = fs.createReadStream("./package.json"); let content = ""; rs.on("open", () => { console.log("start to read"); }); rs.on("data", chunk => { content += chunk.toString("utf8"); }); rs.on("close", () => { console.log("finish read, content is:\n", content); });
借助 stream 的 pipe,一行快速封装一个大文件的拷贝函数
function copyBigFile(src, target) { fs.createReadStream(src).pipe(fs.createWriteStream(target)); }
以上就是如何在Nodejs中使用模块fs文件系统的详细内容,更多关于Nodejs的资料请关注狼蚁SEO其它相关文章!
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程