文件操作
文件读取
我们可以通过readFileSync
或readFile
一次性读取。
// 同步读取
// const data = fs.readFileSync("./path.js");// 默认格式是buffer
const data = fs.readFileSync("./path.js", "utf8"); // 指定utf8格式
console.log(data);
// 异步读取
fs.readFile("./path.js", "utf8", (err, data) => {
if (err) throw err;
console.log(data);
});
我们还可以通过文件流读取
const readStream = fs.createReadStream("./path.js", "utf8");
readStream
.on("data", function (chunk) {
// console.log("读取数据: " + chunk);
})
.on("error", function (err) {
console.log("读取出错: " + err.message);
})
.on("end", function () {
// 没有数据了
console.log("没有数据了");
})
.on("close", function () {
// 已经关闭,不会再有事件抛出
console.log("已经关闭");
});
文件写入
我们可以通过writeFileSync
或writeFile
一次性写入。
注意,如果文件不存在,则创建文件;如果文件存在,则覆盖文件内容
// 同步写入
fs.writeFileSync("./fstest.js", "console.log(123)", "utf8");
// 异步写入
fs.writeFile("./fstest.js", "console.log(123456)", "utf8", (err) => {
if (err) throw err;
console.log("writeFile", "文件写入成功");
});
我们还可以通过文件流写入
const writeStream = fs.createWriteStream("./fstest.js", "utf8");
writeStream.on("close", function () {
// 已经关闭,不会再有事件抛出
console.log("已经关闭");
});
writeStream.write("console.log(123);");
writeStream.write("console.log(456);");
writeStream.end();
文件追加写入
当我们想给某文件追加写入内容的时候,就需要用到下面的方法了。
// 文件同步追加写入
fs.appendFileSync("./fstest.js", "console.log('appendFileSync');");
// 文件异步追加写入
fs.appendFile("./fstest.js", "console.log('appendFile');", (err) => {
if (err) throw err;
console.log("appendFile", "文件追加写入成功");
});
文件拷贝
拷贝,只能拷贝文件,不能拷贝目录。
第一个参数为被拷贝的源文件路径,第二个参数为拷贝到的目标文件路径,如果目标文件不存在,则会创建并拷贝。如果存在则只复制内容。
// 同步拷贝
fs.copyFileSync("./fstest.js", "./fstest2.js");
// 异步拷贝
fs.copyFile("./fstest.js", "./fstest3.js", (err) => {
if (err) throw err;
console.log("copyFile", "文件复制成功");
});
删除文件
注意,只能删除文件,不能删除目录。如果文件不存在则会报错。
// 同步删除文件
fs.unlinkSync("./fstest.js");
// 异步删除文件
fs.unlink("./fstest.js", (err) => {
if (err) throw err;
console.log("文件删除成功");
});
监听文件改动
监听文件改动有两个api,不过他们之间是有区别的,watchFile
返回的是新老文件对象。watch
返回的是事件名和文件名。
fs.watchFile("./fstest.js", { interval: 2000 }, (curr, prev) => {
console.log('watchFile', curr, prev);
});
fs.watch("./fstest.js", {}, (event, filename) => {
console.log('watch', event, filename);
});
目录操作
创建目录
注意创建目录不比创建文件,创建目录如果目录已存在,会报错
// 同步创建
fs.mkdirSync("fstest");
// 异步创建目录
fs.mkdir("fstest", (err) => {
if (err) throw err;
console.log("目录创建成功");
});
删除目录
注意,如果目录不存在则会报错
// 同步删除
fs.rmdirSync("fstest");
// 异步删除
fs.rmdir("fstest", (err) => {
if (err) throw err;
console.log("目录删除成功");
});
遍历目录
只能遍历到第一层,如果需要多层就需要递归
// 同步遍历目录
const files = fs.readdirSync(__dirname, "utf8");
console.log("readdirSync:", files); // [ 'fs.js', 'fstest', 'fstest.js', 'path.js' ]
// 异步遍历目录
fs.readdir(__dirname, "utf8", (err) => {
if (err) throw err;
console.log("readdir:", files); // [ 'fs.js', 'fstest', 'fstest.js', 'path.js' ]
});
文件、目录共有操作
文件目录重命名
既可以修改文件名也可以修改目录名
// 同步重命名
fs.renameSync("fstest.js", "fstest1.js");
fs.renameSync("fstest", "fstest1");
// 异步重命名
fs.rename("fstest.js", "fstest1.js", (err) => {
if (err) throw err;
console.log("rename", "文件名/目录修改成功");
});
文件目录是否存在
检查传入路径下的目录或文件是否可读可写,当有操作权限的时候没有返回值,没有权限或路径非法时抛出一个 Error
对象。
// 同步判断
// 如果成功,则返回undefined,如果失败,则抛出错误
try {
fs.accessSync("./fstest.js");
console.log("accessSync", "fstest.js存在");
} catch (e) {
throw e;
}
// 异步判断
fs.access("./fstest.js", (err) => {
if (err) throw err;
console.log("access", "fstest.js存在");
});
// 判断文件夹
fs.access("./fstest", (err) => {
if (err) throw err;
console.log("access", "fstest存在");
});
文件目录权限
说到文件目录权限,这里我们再复习下操作系统中文件权限相关知识。
在上面表格中,我们可以看出系统中针对三种类型进行权限分配,即文件所有者(自己)、文件所属组(家人)和其他用户(陌生人),文件操作权限又分为三种,读、写和执行,数字表示为八进制数,具备权限的八进制数分别为 4
、2
、1
,不具备权限为 0
。
为了更容易理解,我们可以随便在一个目录中打开 Git
,使用 Linux
命令 ls -al
来查目录中文件和文件夹的权限位
在上面的目录信息当中,很容易看出用户名、创建时间和文件名等信息,但最重要的是开头第一项(十位的字符)。
第一位代表是文件还是文件夹,d
开头代表文件夹,-
开头的代表文件,而后面九位就代表当前用户、用户所属组和其他用户的权限位,按每三位划分,分别代表读(r)、写(w)和执行(x),-
代表没有当前位对应的权限。
以上面fs.js
为例,第一位是-
,所以它是一个文件。后面九位分为rw-
、r--
、r--
三组,所以对应文件所有者、文件所属组、其他用户的权限分别是可读可写、只读、只读。
Node.js
中,标识位代表着对文件的操作方式,如可读、可写、即可读又可写等等,在下面用一张表来表示文件操作的标识位和其对应的含义。
符号 | 含义 |
---|---|
r | 读取文件,如果文件不存在则抛出异常。 |
r+ | 读取并写入文件,如果文件不存在则抛出异常。 |
rs | 读取并写入文件,指示操作系统绕开本地文件系统缓存。 |
w | 写入文件,文件不存在会被创建,存在则清空后写入。 |
wx | 写入文件,排它方式打开。 |
w+ | 读取并写入文件,文件不存在则创建文件,存在则清空后写入。 |
wx+ | 和 w+ 类似,排他方式打开。 |
a | 追加写入,文件不存在则创建文件。 |
ax | 与 a 类似,排他方式打开。 |
a+ | 读取并追加写入,不存在则创建。 |
ax+ | 与 a+ 类似,排他方式打开。 |
简单总结如下:
- r:读取
- w:写入
- s:同步
- +:增加相反操作
- x:排他方式
r+ 和 w+ 的区别,当文件不存在时,r+ 不会创建文件,而会抛出异常,但 w+ 会创建文件;如果文件存在,r+ 不会自动清空文件,但 w+ 会自动把已有文件的内容清空。
在node
中,主要使用chmodSync
、chmod
来进行文件和文件夹权限的修改。
// 同步修改
fs.chmodSync("./fstest.js", "777");
// 异步修改
fs.chmod("./fstest", "777", (err) => {
if (err) console.log(err);
console.log("权限修改成功");
});
获取文件目录对象
文件目录的 stats 对象存储着关于这个文件或文件夹的一些重要信息,如创建时间、最后一次访问的时间、最后一次修改的时间、文章所占字节和判断文件类型的多个方法等等。
// 同步获取
console.log("statSync", fs.statSync("./fstest.js")); // 返回上图的文件对象
console.log("isFile", fs.statSync("./fstest.js").isFile()); // true
console.log("isDirectory", fs.statSync("./fstest").isDirectory()); // true
// 异步获取文件信息
fs.stat("./fstest.js", (err, statObj) => {
if (err) throw err;
console.log("stat", statObj.size); // 34
});
系列文章
Node.js入门之process模块、child_process模块、cluster模块
后记
感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!