深入Nodejs模块fs - 文件系统操作
2021-04-23 07:28
node 的 本文记录了几个文档中没详细描写的问题,可以更好地串联 文件描述符是一个非负整数。它是一个索引值,操作系统可以根据它来找到对应的文件。 在 fs 的很多底层 api 中,需要用到文件描述符。在文档中,描述符通常用 因为操作系统对文件描述符的数量有限制,因此在结束文件操作后,别忘记 close: 所有文件系统的 api 都有同步和异步两种形式。 不推荐使用同步 api,会阻塞线程。 异步写法写起来容易进入回调地狱。 在 node v12 之前,需要自己借助 promise 封装: 在 node v12 中,引入了 fs Promise api。它们返回 Promise 对象而不是使用回调。 API 可通过 fs.Dir 类:封装了和文件目录相关的操作 fs.Dirent 类:封装了目录项的相关操作。例如判断设备类型(字符、块、FIFO 等)。 它们之间的关系,通过代码展示: fs.Stats 类:封装了文件信息相关的操作。它在 注意,关于检查文件是否存在: 在 nodejs 中,stream 是个非常重要的库。很多库的 api 都是基于 stream 来封装的。例如下面要说的 fs 中的 ReadStream 和 WriteStream。 fs 本身提供了 readFile 和 writeFile,它们好用的代价就是性能有问题,会将内容一次全部载入内存。但是对于几 GB 的大文件,显然会有问题。 那么针对大文件的解决方案自然是:一点点读出来。这就需要用到 stream 了。以 readStream 为例,代码如下: 借助 stream 的 pipe,一行快速封装一个大文件的拷贝函数: 由于个人精力有限,很多系列和历史文章没有即时同步,请前往「前端图谱」&「算法题解」,保证您有所收获。fs
文档密密麻麻的 api 非常多,毕竟全面支持对文件系统的操作。文档组织的很好,操作基本分为文件操作、目录操作、文件信息、流这个大方面,编程方式也支持同步、异步和 Promise。fs
文档思路:
文件描述符
fd
来代表。例如:fs.read(fd, buffer, offset, length, position, callback)
。与这个 api 相对应的是:fs.readFile(path[, options], callback)
。const fs = require("fs");
fs.open("./db.json", "r", (err, fd) => {
if (err) throw err;
// 文件操作...
// 完成操作后,关闭文件
fs.close(fd, err => {
if (err) throw err;
});
});
同步、异步与 Promise
同步写法
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 写法
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));
require(‘fs‘).promises
访问。如此一来,开发成本更低了。const fsPromises = require("fs").promises;
fsPromises
.readFile("./package.json", {
encoding: "utf8",
flag: "r"
})
.then(console.log)
.catch(console.error);
目录与目录项
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.stat()
的回调函数中返回。fs.stat("./package.json", (err, stats) => {
if (err) throw err;
console.log(stats);
});
ReadStream 与 WriteStream
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);
});
function copyBigFile(src, target) {
fs.createReadStream(src).pipe(fs.createWriteStream(target));
}
参考链接
最后
下一篇:CSS居中布局
文章标题:深入Nodejs模块fs - 文件系统操作
文章链接:http://soscw.com/index.php/essay/78444.html