深入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.access()。
ReadStream 与 WriteStream
在 nodejs 中,stream 是个非常重要的库。很多库的 api 都是基于 stream 来封装的。例如下面要说的 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));
}
参考链接
文件描述符 Socket 套接字 Nodejs 基础:stream 模块入门介绍与使用 Fastest way to copy file in node.js Using Node.js to Read Really, Really Large Datasets & Files (Pt 1)
最后
觉得不错,帮忙点个推荐呗,您的支持是对我最大的激励 欢迎我的公众号:「心谭博客」,只专注于前端 + 算法的原创分享
深入Nodejs模块fs - 文件系统操作的更多相关文章
- nodejs模块fs——文件操作api
// fs模块常用api // 读取文件 .写入文件 .追加文件. 拷贝文件 .删除文件 // 读取文件 // fs.readFile(path[, options], callback) // fs ...
- 02-Node.js学习笔记-系统模块fs文件操作
2.1.什么是系统模块 Node 运行环境提供的API,因为这些API都是以模块化的方式进行开发的,所有我们又称Node运行环境提供的API为系统模块 3.1系统模块fs文件操作 //f :file ...
- nodeJS之fs文件系统
前面的话 fs文件系统用于对系统文件及目录进行读写操作,本文将详细介绍js文件系统 概述 文件 I/O 是由简单封装的标准 POSIX 函数提供的. 通过 require('fs') 使用该模块. 所 ...
- nodejs模块——fs模块
fs模块用于对系统文件及目录进行读写操作. 一.同步和异步 使用require('fs')载入fs模块,模块中所有方法都有同步和异步两种形式. 异步方法中回调函数的第一个参数总是留给异常参数(exce ...
- nodejs模块——fs模块 读取文件
readFile读取文件 fs.readFile(filename,[option],callback) 方法读取文件. 参数说明: filename String 文件名 option Object ...
- Node.js核心模块-fs文件系统
fs是file-system的简写,文件系统的意思.在Node中如果想要进行文件操作,就必须引入fs这个核心模块. 引入 const fs = require('fs') fs.readFile(pa ...
- nodejs模块——fs模块 使用fs.write读文件
fs.write() fs.read(fd,buffer,offset,length[,position],callback(err,bytesWritten,buffer))接收6个参数. 参数说明 ...
- nodejs模块——fs模块 使用fs.read读文件
使用fs.read读文件 fs.read() 先介绍fs.open. fs.open(path,flags,[mode],callback)方法用于打开文件,以便fs.read()读取. 参数说明: ...
- nodejs模块——fs模块 WriteFile写入文件
WriteFile写入文件 使用fs.writeFile(filename,data,[options],callback)写入内容到文件. 参数说明: filename String 文件名 dat ...
随机推荐
- HDU 6623 Minimal Power of Prime(数学)
传送门 •题意 给你一个大于 1 的正整数 n: 它可以分解成不同的质因子的幂的乘积的形式,问这些质因子的幂中,最小的幂是多少. •题解 把[1,10000]内的素数筛出来,然后对于每个素$P$数遍历 ...
- Kafka Eagle安装详情及问题解答
1.概述 最近有很多同学给笔者留言,说在安装Kafka Eagle的时候,会遇到一些问题,请教如何解决?今天笔者就在这里总结一下安装步骤,和一些安装的注意事项,以及解决方式. 2.内容 在安装Kafk ...
- IdentityServer4 sign-in
原文地址 Sign-in IdentityServer 代表 user 分配token之前,user必须登录IdentityServer Cookie authentication 使用 cookie ...
- 很多.net 程序员不知道又非常重要的 .net高级调试技巧.调试别人的dll方法内的变量
事情是这样的, 最近需要开发Orcale的数据库. 于是使用了EF 加上 Oracle.ManagedDataAccess.Client 这个Oracle.ManagedDataAccess 很好用, ...
- Channel 9视频整理【6】
GiGi Huang https://channel9.msdn.com/Niners/GiGiHuang
- Python正则表达式之findall疑点
在findall中使用()进行分组时,得出的结果会优先提取分组的,比如下面这个例子 In [46]: re.findall(r"www.(baidu|163).com", &quo ...
- AI炼丹 - 深度学习必备库 numpy
目录 深度学习必备库 - Numpy 1. 基础数据结构ndarray数组 1.1 为什么引入ndarray数组 1.2 如何创建ndarray数组 1.3 ndarray 数组的基本运算 1.4 n ...
- Excel解除'工作表保护密码',并复原密码设定
前提要求 Office 2003(也就是老版的.xls文件) 用到宏操作 可以解除[审阅->保护工作表]的密码保护,其他的密码保护不能处理. 解决方案 打开需解除保护密码的Excel文件(.xl ...
- Qt listWidget和QListWidgetItem的简单使用
简单的来实习了下 #include "mainwindow.h" #include "ui_mainwindow.h" #include<QListWid ...
- mysql主从同步--读写分离。
1.mysql 安装参考 https://www.cnblogs.com/ttzzyy/p/9063737.html 2. 主mysql,从mysql 指定配置文件启动 mysqld --defaul ...