赞
踩
文章目录
上一篇文章我们介绍了nodejs的事件,如新建或继承事件对象,绑定事件对象等,详见: Node.js后端开发 - 基础篇 #5 事件 这篇文章我们将介绍nodejs的读写文件(同步,异步),那么怎么读写文件?怎么把文件的内容读取出来,然后再把它写到另一个文件中,并且通过这篇文章我们来简单理解同步和异步的关系。好了废话少说,我们来开始编码!
我们可以在app.js里面写入以下代码:
- //导入nodejs文件系统的一个库
- var fs = require('fs');
-
- //参数1:文件名路径,路径需要加双引号。
- //因为是当前目录,所以直接可以写文件名
- //参数2:编码格式
- var readMe = fs.readFileSync("readMe.txt","utf-8");
我们手动新建一个文件readMe.txt,写入内容:读我啊 read me
我们来看一看读取出来的结果:
- MacBook-Pro:hello-nodejs luminal$ node app
- 读我啊 read me
- MacBook-Pro:hello-nodejs luminal$
下面我们来看看写的方法,代码如下:
- var fs = require('fs');
-
- var readMe = fs.readFileSync("readMe.txt","utf-8");
-
- //参数1:要写入的文件名路径。没有的话,它会自动新建
- //参数2:要写入的内容。
- fs.writeFileSync("writeMe.txt", readMe);
- //fs.writeFileSync("writeMe.txt", "190910马老师-怒放的生命");
我们来看看输出结果:
- MacBook-Pro:hello-nodejs luminal$ node app
- MacBook-Pro:hello-nodejs luminal$
因为是写入操作,我们没有日志输出,下面我们会发现当前目录,自动生成了一个 writeMe.txt 的文件
上面是把 readMe 这个对象的内容写进去了。
当然你也可以自定义内容写进去 fs.writeFileSync("writeMe.txt", "190910马老师-怒放的生命"); 这个结果就不贴图了!
上面演示的 readFileSync、writeFileSync都是同步方法,其实sync英文就是同步的意思,那么有同步就必然有异步,下面我们来看看下面的代码
- var fs = require('fs');
-
- var readMe = fs.readFileSync("readMe.txt","utf-8");
-
- console.log(readMe);
-
- console.log("finished");
我们来看看输出结果:
- MacBook-Pro:hello-nodejs luminal$ node app
- 读我啊 read me
- finished
- MacBook-Pro:hello-nodejs luminal$
意思上面四行代码是同步执行的,从头到尾一行一行依次执行下来。那如果文件"readMe.txt"非常大,那么这个读取的时间就会很长,后面要执行的内容只能排队等待执行,那么这种情况显然不合理!
nodejs执行JavaScript的时候它是单线程的,这里要注意的是:我并没有说nodejs是单线程的。这种I/O操作,比如说像数据库连接是很常见的,也是最耗时的。那么怎么来解决这个问题呢?这个时候我们可以用到异步,下面我们修改一下代码如下:
- var fs = require('fs');
-
- var readMe = fs.readFile("readMe.txt","utf-8",function(err, data) {
- console.log(data);
- });
-
- // 延迟5秒执行。我们可以用这个模拟感受下,阻塞的状态!
- //也就是说,有如下耗时的同步操作,那就会阻塞整个线程的运行,
- //就算是上面异步的方法,也会被阻塞。当遇见这种情况,这时候你写nodejs,
- //都是要用异步的方法来处理
- //var waitTill = new Date(new Date().getTime() + 5 * 1000);
- //while (waitTill > new Date()) {}
-
- console.log("finished");
我们来看看输出结果:
- MacBook-Pro:hello-nodejs luminal$ node app
- finished
- 读我啊 read me
- MacBook-Pro:hello-nodejs luminal$
我们会发现 “finished” 先输出出来了,那么怎么回事呢?
readFile是一个异步方法,修改的代码执行的是异步事件、异步的I/O操作,nodejs执行JavaScript的时候它是单线程的,上面代码的语句还是一行一行的执行的。那么 “finished” 为什么会先输出出来?
其实是这样的,nodejs它维护了一个事件队列,上面三行语句中,第一句还是会先执行,执行第二句的时候它就在事件队列当中注册了一个事件,告诉这个事件队列,我将要去读取一个文件。但是里面的回调函数并没有被马上执行,这个操作是瞬间完成的,完成之后它就会执行主线程的第三条语句 console.log("finished");
当主线程空闲的时候,它就会去找事件队列里面的事件,把它取出来。在此同时发起一个线程去执行事件队列里面的事件,在这里是读取一个文件,当读完成功以后,它再告诉主线程我已经执行成功。
因为I/O操作它有时候是很耗时的,你不能阻塞别的操作,不能让别的操作一直在等待它的执行,应该是开启另一个线程就执行这个I/O操作,它执行成功以后再通知主线程去执行它。
有readFile方法必然会有与之对应的writeFile方法,下面我们来看看代码:
- var fs = require('fs');
-
- // var readMe = fs.readFile("readMe.txt","utf-8",function(err, data) {
- // console.log(data);
- // });
- var data = "写写写";
- fs.writeFile("writeMe.txt", data, function() {
- console.log("写入完毕!");
- });
-
- console.log("finished");
我们来看看输出结果:
- MacBook-Pro:hello-nodejs luminal$ node app
- finished
- 写入完毕!
- MacBook-Pro:hello-nodejs luminal$
同样的,writeFile方法也是异步的方法,所以"finished"先输出。同时我们会发现,写入的内容已经写进去了,如下图:
可参考的api:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。