7、NodeJs内置负责读写文件的fs模块详解

阅读() @2019-03-17 16:05:17

fs是NodeJs内置的用于读写文件的模块,与其他内置的模块不同的是,fs模块同时提供了同步和异步的方法。

回顾一下什么是异步方法。因为JavaScript的单线程模型,执行IO操作时,JavaScript代码无需等待,而是传入回调函数后,继续执行后续JavaScript代码。比如jQuery提供的getJSON()操作:

$.getJSON('http://www.zymseo.com/node/', function (data) {
    console.log('IO结果返回后执行...');
});
console.log('不等待IO结果直接执行后续代码...');

而同步的IO操作则需要等待函数返回:

// 根据网络耗时,函数将执行几十毫秒~几秒不等:
var data = getJSONSync('http://www.zymseo/com/node/');

同步操作的好处是代码简单,缺点是程序将等待IO操作,在等待时间内,无法响应其它任何事件。而异步读取不用等待IO操作,但代码较麻烦。

一、NodeJs异步读取文件内容:

'use strict'

var fs = require('fs');

fs.readFile('1.txt', 'utf8', function(error, data){
    if(error){
        console.log(error);
        return;
    }
    console.log(data);
});

注意:我这边1.txt与当前js脚本在同一目录,并且txt文件的编码是utf8。

异步读取时,传入的回调函数接收两个参数,当正常读取时,error参数为null,data参数为读取到的String。当读取发生错误时,error参数代表一个错误对象,data为undefined。这也是Node.js标准的回调函数:第一个参数代表错误信息,第二个参数代表结果。后面我们还会经常编写这种回调函数。

如果我们要读取的文件不是文本文件,而是二进制文件,怎么办?下面的例子演示了如何读取一个图片文件:

'use strict'

var fs = require('fs');

fs.readFile('test.jpg', function(error, data){
    if(error){
        console.log(error);
        return;
    }
    console.log(data);
});

当读取二进制文件时,不传入文件编码时,回调函数的data参数将返回一个Buffer对象。在Node.js中,Buffer对象就是一个包含零个或任意个字节的数组(注意和Array不同)。

Buffer对象可以和String作转换,例如,把一个Buffer对象转换成String:

console.log(data.toString('utf8'));

String同样可以转换成Buffer对象,代码如下:

console.log(new Buffer(data, 'utf8'));

二、NodeJs同步读取文件:

'use strict'

var fs = require('fs');

try{
    var rs = fs.readFileSync('1.txt', 'utf8');
    rs ? console.log(rs) : console.log('出错');
}catch(error){
    console.log(error);
}

可见,原异步调用的回调函数的data被函数直接返回,函数名需要改为readFileSync,其它参数不变。

使用try catch是为了捕获错误!

同样的,读取二进制数据的时候,不要添加编码参数即可,代码如下:

'use strict'

var fs = require('fs');

try{
    var rs = fs.readFileSync('test.jpg');
    rs ? console.log(rs) : console.log('出错');
}catch(error){
    console.log(error);
}

三、NodeJs异步写入文件:

'use strict'

var fs = require('fs');

var data = 'this is 2.txt';
fs.writeFile('2.txt', data, function(error){
    error ? console.log(error) : console.log('写入成功');
});

写入文件的时候,回调函数中只有一个error参数,并且默认以ut8编码写入。

四、NodeJs同步写入文件:

'use strict'

var fs = require('fs');

var data = 'this is 2.txt!';
var status = fs.writeFileSync('2.txt', data);
status ? console.log(status) : console.log('写入成功');

五、使用stat异步获取文件的详细信息:

'use strict'

var fs = require('fs');

fs.stat('test.jpg', function(error, data){
    error ? console.log(error) : console.log(data);
});

同样的还有一个statSync方法同步获取文件信息。

那么问题来了,在工作中具体应该使用同步还是异步呢?

由于Node环境执行的JavaScript代码是服务器端代码,所以,绝大部分需要在服务器运行期反复执行业务逻辑的代码,必须使用异步代码,否则,同步代码在执行时期,服务器将停止响应,因为JavaScript只有一个执行线程。

服务器启动时如果需要读取配置文件,或者结束时需要写入到状态文件时,可以使用同步代码,因为这些代码只在启动和结束时执行一次,不影响服务器正常运行时的异步执行。

六、检测文件变化,输入当前和上一次变动的文件信息

fs.watchFile('test1.txt', function(cur, prev){
    console.log(cur);
    console.log(prev);
});

七、检测某个目录的变化

fs.watch('../readline', function(eventType, fileName){
    console.log('事件类型是:' + eventType);
    fileName ? console.log('文件名是:' + fileName) : console.log('文件名不存在');
});

(持续更新中!)

微信二维码