fs 文件系统

NodeJS提供了fs核心模块,用于文件流读写、文件目录操作等,下面简单展示一些常用的例子代码。

同步读写文件

fs.readFileSync()fs.writeFileSync()使用同步的方式读写文件,下面是一个例子。

const fs = require("fs");

const txt1 = fs.readFileSync("./a.txt", "utf8");
console.log(txt1);

const txt2 = "你好";
fs.writeFileSync("./b.txt", txt2);

这里要注意,我们知道NodeJS中JavaScript脚本是单线程运行的,使用同步的方式读写较大的文件会导致程序阻塞,因此在NodeJS中极少使用上面的写法,通常使用异步方式读写文件。

异步读写文件

fs.readFile()fs.writeFile()使用异步的方式读写文件,下面是一个例子。

const fs = require("fs");

fs.readFile("a.txt", "utf8", function(err, data) {
    fs.writeFile("b.txt", data, "utf8", function(err) {
        console.log("write finished");
    });
});

console.log("test");

输出结果如下:

test
write finished

上面代码中以异步方式读写文件,和同步方式的区别就是异步方式中,我们需要传入回调函数(callback)作为参数,回调函数会在读或写完成时被调用,实际的IO操作和主线程是异步的。

使用流读写文件

上文使用的fs.readFile()fs.writeFile()等函数都是一次性把文件读入内存或是写入文件,对于很大的文件或是网络程序,这种做法肯定是不行的。这种情况下,我们通常使用流和一个缓冲区对数据进行操作。

下面例子代码中,我们使用流读写一个大文件。

const fs = require("fs");

const readStream = fs.createReadStream("a.exe");
const writeStream = fs.createWriteStream("b.exe");

//输入流读入buffer,并立刻写到输出流
readStream.on("data", function(buffer) {
    writeStream.write(buffer);
});

readStream.on("end", function() {
    console.log("read finished");
    //当输入流读完关闭输出流
    writeStream.end();
});
writeStream.on("finish", function() {
    console.log("write finished");
});

管道

在Linux的bash中,我们经常使用ls | grep pattern这样的管道操作,ls命令的输出被对接到了grep程序的输入流上,NodeJS中的管道也是类似的概念,我们可以把一个流对接到另一个流上,实现数据的转运。下面是使用pipe实现文件复制的例子。

const fs = require("fs");

const readStream = fs.createReadStream("a.exe");
const writeStream = fs.createWriteStream("b.exe");

//使用管道进行数据转运
readStream.pipe(writeStream);

readStream.on("end", function() {
    console.log("read finished");
    writeStream.end();
});
writeStream.on("finish", function() {
    console.log("write finished");
});

fs/promises模块

通过前面内容我们可以看到,fs模块的API大多是以回调函数的形式提供的,而非原生支持Promise,这也导致难以用上JavaScript最新的async/await语法,在老的版本中我们必须自己封装返回Promise的方法,或是使用内置的promisify函数等。

然而,这一状况从node 14版本开始得到了改善,这一版本引入了fs/promises模块,它的API和原版的fs基本一致,但其返回值为Promise,我们可以使用async/await写法调用这些API,并使用try/catch捕获异常。

有关fs/promises的内容这里就不展开介绍了,用法和原版的fs基本一致,具体参考文档即可。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap