流(stream)的概念:
fs.readFile('1.html',(err,buffer)=>{
res.write(buffer);
})
这样读文件:他先把整个文件完全读到内存里面去,读到服务器的内存里面,然后再一把把它发出去,有两个缺点:
1)占用内存
2)资源使用是不均匀的 -> 刚开始一直在读读读 文件,一直是磁盘在忙活,等到什么时候一个不拉的全部读完了往外发,这个时候磁盘就空闲了,网络就该忙忙忙了。这就相当于有两个员工,一个人干活的时候,另一个人在闲着。
应该如何做?
- 读一块就发一块。这样做有两个好处:
(1)省内存,因为内存只需要存这一块的东西就行
(2)磁盘和网络一块忙活,同时进行,这样效率高。
流操作简单的说就是读一块,发一块。
如果在读取的时候是读的一张1.jpg(本地已存在),写入写的是2.txt(本地不存在),进行读写连接,那么就会生成一个和1.jpg同等大小的2.txt文件,这个txt文件中全是图片信息,其实还是copy了1.jpg的图片,把2.txt拖入图片查看器,还是能看到图片,后缀名是给人看的,置于里面的东西是给机器看的。
另外:读和写连到一起,写的事件会自动喂到读的身上,一旦写的流需要暂停,那么读的流也会停在那等着写,等什么完事,再读。流方便就方便在不用我们自己去控制,系统会帮我们完成这样的操作。
读写流:在什么样的情况下我需要既读又写?
- 比如说压缩 :左边有个一个原始数据流,右边输出一个压缩后的数据流;我就在中间相当于一个盒子,这边进,那边出。
- 比如说加密:左边-原始数据流,右边加密后的数据流。
rs.on('error',err=>{
res.writeHeader(404); res.write('not found'); res.end();})
这个函数可以捕获错误,读取的错误,比如我们访问(即读取)一个不存在的文件,会把服务器进程结束抛出错误,但是有了这个函数就不会影响服务器进程,服务器也不会停掉了。并且告诉浏览器状态码和信息。
在进行读写文件前首先检查文件存不存在:
其实上面的在发送给浏览器时候,设置了响应头,能让浏览器解析压缩的文件显示出来,如果不设置,浏览器识别不了,就会下载下来了,这样会不会影响性能?、
回答:不会的,因为网络传输是较慢的,设置了头就相当于传输的途中浏览器进行了解压操作,对于现在计算机来说,解压是非常快的(比着网速),所以后台把文件压缩后,设置头浏览器解析,变相的也节省了网络传输的时间,因为体积小了嘛~!电脑的确在解压的时候会造成一丁点CPU的负担,但是可以忽略不计。现在的这种设置头的发送压缩文件,就是还没有存储在服务器的磁盘中,就已经发出去了。在服务器的内存中压缩,没有写磁盘。
总结,这样做其实就是后台做了压缩,让传输给浏览器的时候更小,但是又不想变成压缩包传给前台,所以设置了响应头。
万一在读取的时候,读着读着就错了,我们用res.on('error') 这个函数去进行捕获,保证服务器不会挂掉终止进程。还可以用启动器,它可以帮助我们来重启服务,崩了没事,他会帮助重启,可能会影响一个两个访问,但对于绝大多数用户毫无感知。
启动器:
forever
安装:npm i forever -g
安装完成 后运行:
forever start xx.js
这样就算把命令行窗口关掉,他还在,甚至把电脑关了,他也会自动帮你重启。
命令:
forever start xx.js -> 运行服务
forever list - > 查看正在运行的服务
forever restart xx.js -> 停掉重开
forever stop xx.js - > 关掉指定服务
forever stopall -> 关闭所有,基本不用
forever start xxx.js -l c:/a.log -e c:/err.log -a ->运行文件打印日志,-l后面的是打印日志到指定盘中的什么文件,-e后面的是打印错误此案系到指定盘中的什么文件,-a是不要清除之前的日志,继续往后添加。