好久没看node了,一年前雄心壮志要学一门后台语言,折腾了PHP和nodejs但由于种种原因并没有坚持下来,学的东西也零零散散,并没有做系统的整理,前两天由于公司业务需要用到node,所以就又温习了一遍文件操作部分,不算熟悉不算陌生,问题解决了,也重新激起了心底对node的喜爱,因为它真的很强大,java/PHP等服务器端语言中,为每一个客户端连接创建一个新的线程,每个线程需要耗费大约2MB的内存,理论上来说具有8GB内存的服务器可以同时连接的最大用户数只有4000个左右,而nodejs修改了客户端到服务器端的连接方法,它并不为每个客户端连接创建一个新的线程,而是为每个客户端连接触发一个在nodejs内部进行处理的事件,因此它可以同时处理多达几万个用户的客户端连接。这么强大的nodejs,对前端开发者来说语法又相对友好,想朝全栈发展的front-end engineer nodejs一定是首选。回到正题,总结一下这两天复习的文件操作。
nodejs中使用fs模块来实现所有有关文件及目录的创建,写入及删除操作。
1. 同步方法与异步方法
在fs模块中,所有对文件及目录的操作都可以使用同步与异步这两种方法。
(1)区别:
- 同步方法(有Sync后缀)立即返回操作结果,在使用同步方法执行的操作结束之前,不能执行后续代码。
- 使用场景:读取配置文件并启动服务器
var fs = require('fs');
var data = fs.readFileSync('./index.html','utf8');
//等待操作返回结果,然后利用该结果
console.log(data);
- 异步方法将操作结果作为回调函数的参数进行返回,在方法调用之后,可以立即执行后续代码。在大多数情况下,都使用异步方法。
var fs = require('fs');
fs.readFile('./index.html','utf8',function(err,data) {
//操作结果作为回调函数的第二个参数返回
console.log(data);
});
同时调用多个异步方法时,并不能确保操作结果的返回顺序。如果需要确保在一个文件读取完毕后再读取另一个文件,方法如下:
var fs = require('fs');
fs.readFile('./file.html',function(err,data) {
//在回调函数中读取另一个文件
fs.readFile('./other.html',function(err,data) {
//回调函数代码略
});
});
2.对文件执行读写操作
(1)读文件
fs.readFile(filename,[options],callback)
- filename参数:用于指定读取文件的完整文件路径及文件名参数;
- options参数:为可选参数,值为一个对象;
- flag属性:指定对该文件采取什么操作,默认值为’r’;
- encoding属性:指定使用何种编码方式来读取该文件,可指定属性值为’utf8’,’ascii’与’base64’;
- callback参数:用于文件读取完毕时执行的回调函数。
function(err,data) {
//回调函数代码略
}
例1:使用readFile方法读取文件
var fs = require('fs');
fs.readFile('.test.txt','utf8',function(err,data) {
if(err) console.log('an error occurred while reading the file');
//output file contents in console
else console.log(data);
});
例2:使用同步方法读取文件
var fs = require('fs');
try{
var data=fs.readFileSync('./test.txt','utf8');
//output file contents in console
console.log(data);
}
catch(ex) {
console.log('an error occurred while reading file');
}
(2)写文件
fs.writeFile(filename,data,[options],callback)
- filename参数:用于指定需要被写入文件的完整文件路径及文件名;
- data参数:用于指定需要写入的内容;
- options参数:指定写入文件时需要使用的选项
- flag属性:用于指定对该文件采取何种操作,默认值为’w’;
- mode属性:用于指定当文件被打开时对文件的读写权限,默认值为0666。由4位数字组成,第一位必须是0,第二位规定文件或目录所有者的权限,第三位规定文件或目录所有者所属用户组的权限,第四位规定其他人的权限。
- 1:执行权限
- 2:写权限
- 4:读权限
- encoding属性:指定使用何种编码格式来写入该文件。
- callback参数:用于文件执行完毕时执行的回调函数。
例3:使用writeFile方法完整写入文件
var fs = require('fs');
var data = new Buffer('i love programming');
fs.writeFile('./message.txt',data,function(err) {
if(err) console.log('fail to write file operation');
else console.log('successful write file operation');
});
例4:使用writeFile方法追加数据
var fs = require('fs');
var options={
flag:'a'
}
fs.writeFile('./message.txt','additionalData',options,function(err) {
if(err) console.log('fail to write file operation');
else console.log('successful write file operation');
});
例5:使用writeFile方法复制图片文件
var fs = require('fs');
fs.readFile('./a.gif','base64',function(err) {
fs.writeFile('./b.gif',data.toString(),'base64',function(err) {
if(err) console.log('fail to write file operation');
else console.log('successful write file operation');
});
});
例6:使用同步方式写入文件
fs.writeFileSync(filename,data,[options])
例7:使用appendFile方法将一个字符串或一个缓冲区中的数据追加到一个文件底部
var fs = require('fs');
fs.appendFile('./message.txt','additionalData','utf8',function(err) {
if(err) console.log('append file operation failed');
else console.log('append file operation successed');
});
(3)从指定位置处开始读文件
fs.open(filename,flags,[mode],callback)
var fs = require('fs');
fs.open('./message.txt','r',function(err,fd) {
console.log(fd);
});
使用同步方式打开文件时,使用openSync方法
var fd = fs.openSync(filename,flags,[mode])
fs.read(fd,buffer,offset,length,positon,callback)
function (err,bytesRead,buffer) {
//回调函数代码略
});
例7:read方法使用实例
var fs = require('fs');
fs.open('./message.txt','r',function(err,fd) {
var buf=new Buffer(255);
//一个汉字的utf编码为三个字节数据
fs.read(fd,buf,0,9,3,function(err,bytesRead,buffer) {
console.log(buffer.slice(0,bytesRead).toString());
});
});