详解nodeJS中读写文件方法的区别


Posted in NodeJs onMarch 06, 2017

导言:nodejs中所有与文件相关的操作都在fs模块中,而读写操作又是我们会经常用到的操作,nodejs的fs模块针对读操作为我们提供了readFile,read, createReadStream三个方法,针对写操作为我们提供了writeFile,write, createWriteStream三个方法,下面分析一下它们的区别:

一、readFile和writeFile

1、readFile方法是将要读取的文件内容完整读入缓存区,再从该缓存区中读取文件内容,具体操作如下:

fs.readFile('./test.txt', 'utf8', function(err, data){
  console.log(data); 
});

与其对应的同步方法为:

var data = fs.readFileSync('./test.txt', 'utf8');
console.log(data);

同步方法和异步方法的区别是:在使用同步方法执行的操作结束之前,不能执行后续代码的执行;而异步方法将操作结果作为回调函数的参数进行返回,方法调用之后,就可以立即执行后续的代码,读取完毕后会调用对应的回调函数。

2、writeFile方法是将要写入的文件内容完整的读入缓存区,然后一次性的将缓存区中的内容写入都文件中,其同步和异步具体操作如下:

//异步方法
fs.writeFile('./message.txt', '这是第一行',function(err){
  if(err) console.log('写文件操作失败');
  else console.log('写文件操作成功');
});

//同步方法
fs.writeFileSync('./message.txt','这是第一行');

以上的读写操作,Node.js将文件内容视为一个整体,为其分配缓存区并且一次性将文件内容读取到缓存区中,在这个期间,Node.js将不能执行任何其他处理。所以当读写大文件的时候,有可能造成缓存区“爆仓”。

二、read和write

1、read或readSync方法读取文件内容是不断地将文件中的一小块内容读入缓存区,最后从该缓存区中读取文件内容,具体操作如下:

var fs = require('fs');
fs.open('./message.txt','r',function(err,fd){
  var buf = new Buffer(225);
  //读取fd文件内容到buf缓存区
  fs.read(fd,buf,0,9,3,function(err,bytesRead,buffer){
    console.log(buf.slice(0,bytesRead).toString());
  }); 
  var buff = new Buffer(225);
  //位置设置为null会默认从文件当前位置读取
  fs.read(fd,buff,0,3,null,function(err,bytesRead,buffer){
    console.log(buff.slice(0,bytesRead).toString());
  });

  var buffer = new Buffer(225);
  //同步方法读取文件
  var bytesRead = fs.readFileSync(fd,buffer,0,9,3);
  console.log(bytesRead);
  console.log(buffer.slice(0,bytesRead).toString());
});

2、write或writeSync方法写入内容时,node.js执行以下过程:1将需要写入的数据写入到一个内存缓存区;2待缓存区写满后再将缓存区中的内容写入到文件中;3重复执行步骤1和步骤2,知道数据全部写入文件为止。具体操作如下:

var fs = require('fs');
var buf = new Buffer('我喜爱编程');
fs.open('./mess.txt','w',function(err,fd){
  fs.write(fd,buf,3,9,0,function(err,written,buffer){
    fs.write(fd,buf,12,3,null,function(err,written,buffer){
      if(err) console.log('写文件操作失败');
      console.log('写文件操作成功');
    });
  });
  //同步写入
  fs.writeSync(fd,buf,3,9,0);
});

以上读写操作,node.js会将文件分成一块一块逐步操作,在读写文件过程中允许执行其他操作。

但有的时候我们并不关心整个文件的内容,而只关注从文件中读取到的某些数据,以及读取到数据时需要执行的处理,这时我们可以使用文件流来处理。

三、createReadStream和createWriteStream

1、createReadStream方法创建一个将文件内容读取为流数据的ReadStream对象,方法如下所示:

var fs = require('fs');
var readStream = fs.createReadStream('./message.txt',{start:3,end:12});
readStream.on('open',function(fd){
  console.log('开始读取文件');
});
readStream.on('data',function(data){
  console.log('读取到数据:');
  console.log(data);
});
readStream.on('end',function(){
  console.log('文件已全部读取完毕');
});
readStream.on('close',function(){
  console.log('文件被关闭');
});
readStream.on('error',function(err){
  console.log('读取文件失败');
});

2、createWriteStream方法创建一个将流数据写入文件中的WriteStream对象,方法如下所示:

var fs = require('fs');
var file = fs.createReadStream('./message.txt');
var out = fs.createWriteStream('./anotherMessage.txt');
file.on('data',function(data){
  out.write(data);
});
out.on('open',function(fd){
  console.log('需要被写入的文件已打开');
});
file.on('end',function(){
  //将操作系统缓存区中的数据全部写入文件
  out.end('再见',function(){
    console.log('文件全部写入完毕');
    console.log('共写入'+out.bytesWritten+'数据');
  });
});

以上方法可以对读写文件的过程中进行监听,并定义相关的方法pause和resume暂停或恢复文件的读取操作,可以监听写入时缓存区数据是否已满或者是否已全部输出,如下所示:

//监听writeStream对象的drain事件
var fs = require('fs');
var out = fs.createWriteStream('./test1.txt');
for(var i=0;i<10000;i++){
  //返回true或false true代表缓存区已满
  var flag = out.write(i.toString());
  console.log(flag);
}
out.on('drain',function(){
  console.log('操作系统缓存区中的数据已全部输出');
  var out = fs.createWriteStream('./test2.txt');
  for(var i=0;i<10;i++){
    var flag = out.write(i.toString());
    console.log(flag);
  }
  out.on('drain',function(){
    console.log('操作系统缓存区中的数据已全部输出');
  });
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
Nodejs实现的一个简单udp广播服务器、客户端
Sep 25 NodeJs
nodejs事件的监听与触发的理解分析
Feb 12 NodeJs
nodejs中实现阻塞实例
Mar 24 NodeJs
nodejs实现bigpipe异步加载页面方案
Jan 26 NodeJs
nodejs如何获取时间戳与时间差
Aug 03 NodeJs
NodeJS远程代码执行
Aug 28 NodeJs
用nodeJS搭建本地文件服务器的几种方法小结
Mar 16 NodeJs
详解nodejs微信公众号开发——4.自动回复各种消息
Apr 11 NodeJs
深入理解Nodejs Global 模块
Jun 03 NodeJs
NodeJS设计模式总结【单例模式,适配器模式,装饰模式,观察者模式】
Sep 06 NodeJs
NodeJS 将文件夹按照存放路径变成一个对应的JSON的方法
Oct 17 NodeJs
nodejs基础之常用工具模块util用法分析
Dec 26 NodeJs
详谈Angular路由与Nodejs路由的区别
Mar 05 #NodeJs
async/await与promise(nodejs中的异步操作问题)
Mar 03 #NodeJs
nodejs搭建本地服务器并访问文件的方法
Mar 03 #NodeJs
NodeJS仿WebApi路由示例
Feb 28 #NodeJs
Nodejs多站点切换Htpps协议详解及简单实例
Feb 23 #NodeJs
NodeJs下的测试框架Mocha的简单介绍
Feb 22 #NodeJs
基于Nodejs利用socket.io实现多人聊天室
Feb 22 #NodeJs
You might like
那些年一起学习的PHP(三)
2012/03/22 PHP
PHP数据过滤的方法
2013/10/30 PHP
php读取3389的脚本
2014/05/06 PHP
php中json_encode UTF-8中文乱码的更好解决方法
2014/09/28 PHP
常用参考资料(手册)下载或者链接
2006/07/22 Javascript
JS+CSS实现仿新浪微博搜索框的方法
2015/02/24 Javascript
javascript日期格式化方法汇总
2015/10/04 Javascript
js HTML5 Ajax实现文件上传进度条功能
2016/02/13 Javascript
AngularJS 表达式详细讲解及实例代码
2016/07/26 Javascript
React Native 集成jpush-react-native的示例代码
2017/08/16 Javascript
Vue父子模版传值及组件传值的三种方法
2017/11/27 Javascript
巧妙运用v-model实现父子组件传值的方法示例
2019/04/07 Javascript
JS实现的简单tab切换功能完整示例
2019/06/20 Javascript
Vue实现PC端靠边悬浮球的代码
2020/05/09 Javascript
单线程JavaScript实现异步过程详解
2020/05/19 Javascript
基于react项目打包css引用路径错误解决方案
2020/10/28 Javascript
[46:04]Liquid vs VP Supermajor决赛 BO 第四场 6.10
2018/07/05 DOTA
python将字符串转换成数组的方法
2015/04/29 Python
对Python的Django框架中的项目进行单元测试的方法
2016/04/11 Python
详解Python3 中hasattr()、getattr()、setattr()、delattr()函数及示例代码数
2018/04/18 Python
Python的控制结构之For、While、If循环问题
2020/06/30 Python
Python改变对象的字符串显示的方法
2020/08/01 Python
Python做图像处理及视频音频文件分离和合成功能
2020/11/24 Python
使用简单的CSS3属性实现炫酷读者墙效果
2014/01/08 HTML / CSS
Expedia韩国官网:亚洲发展最快的在线旅游门户网站
2018/02/26 全球购物
简单说下OSPF的操作过程
2014/08/13 面试题
企业文化口号
2014/06/12 职场文书
生死牛玉儒观后感
2015/06/11 职场文书
篮球比赛通讯稿
2015/07/18 职场文书
商业计划书格式、范文
2019/03/21 职场文书
导游词之长城八达岭
2019/09/24 职场文书
导游词之秦始皇兵马俑博物馆
2019/09/29 职场文书
nginx如何将http访问的网站改成https访问
2021/03/31 Servers
Python基础之操作MySQL数据库
2021/05/06 Python
MYSQL 的10大经典优化案例场景实战
2021/09/14 MySQL
Python  lambda匿名函数和三元运算符
2022/04/19 Python