NodeJS文件读取:感恩常在--抓把糖果,愉悦客人

通过上一篇文章“服务器:一行代码 = 一个的HTTP服务器”,我们已经开启了之旅,开发了一个监听在8000端口的HTTP服务器,虽然功能很简单,但是,已经让我们感受到用开发服务器是一件简单、愉快的事情 。现在,我们按着既定的目标----将电脑里的文件共享给手机,继续前进 。
老规矩,先上一个图:

NodeJS文件读取:感恩常在--抓把糖果,愉悦客人

文章插图
回到我们的项目目标,要实现的功能是:当有客户端向服务器发送请求的时候,就读取电脑D:\下面的
.png的图片文件作为响应,反馈给客户端,代码如下:
1 var http = require( 'http' ); 2 var fs = require('fs'); 34 var file_path = "D:\\ilinkit_logo.png" ; 5 var file_stream; 67 var server =http.createServer( function ( request ,response ){ 8file_stream = fs.createReadStream( file_path );9file_stream.on( 'data' , function( chunk ){10response.write( chunk );11} ); 12file_stream.on( 'end' , function(){13response.end( "" );14console.log( "文件读取完毕" );15} );16file_stream.on('error', function(err){17response.end( "文件读取失败!" );18});19 } );20 server.listen( 8000 );21 console.log( 'HTTP服务器启动中,端口:8000.....' );
这个代码也比较简单,下面对关键的代码行说明如下:
第2行:加载fs模块,因为我们要用它来读取电脑中的本地文件 。
第8行:当有客户端有发送请求时,用fs读取文件到文件流之中 。
文件流的概念,和Java、C++中文件流的概念类似,相当于建立了一个管道,这个我们待会儿在优化版本中会再次体会到 。
第9行、第12行、第16行:分别实现在文件读取过程中,有数据读取到时(data)、数据读取结束(end)和读取数据发生错误时(error)的响应函数 。
第10行:将从文件读取到数据,直接通过响应给客户端 。
验证方式如下:
1. 启动服务器:打开命令行,进入js脚本所在的位置,执行:node .js,如下所示:
NodeJS文件读取:感恩常在--抓把糖果,愉悦客人

文章插图
2. 打开浏览器,输入::8000,显示如下:
NodeJS文件读取:感恩常在--抓把糖果,愉悦客人

文章插图
当完成对客户端请求的响应之后,服务器端输出日志:文件读取完毕,如下所示:
NodeJS文件读取:感恩常在--抓把糖果,愉悦客人

文章插图
改进1:
前面我们提到,读取文件时,使用的是用fs.返回文件流,而给客户端响应数据的对象,也像一个管道,
也像一个“流”,这么看,向客户端响应文件时,是不是将两个管道对接起来就OK了呢?还真有这样的机制 。
NodeJS文件读取:感恩常在--抓把糖果,愉悦客人

文章插图
下面我们来看一下改进之后的代码:
1 var http = require( 'http' ); 2 var fs = require('fs'); 34 var file_path = "D:\\ilinkit_logo.png" ; 5 var file_stream; 67 var server =http.createServer( function ( request ,response ){ 8file_stream = fs.createReadStream( file_path );9file_stream.pipe( response );10 } );11 server.listen( 8000 );12 console.log( 'HTTP服务器启动中,端口:8000.....' );
重点看第9行:通过fs.将文件数据流之后,直接调用pipe函数,.pipe(); 将文件中的数据响应给客户端 。
相当于,你去中药房取药,之前的方式是:你到药房的窗口,把药方给里面的工作人员,工作人员依据药方的清单,到货架上一样一样的取药 。全部取完之后,拿个袋子一装,然后跟你说:“都在这里了,您核对一下 。”
改进之后呢?整个过程变得自动化,不需要工作人员一样一样的取药 。你到窗口在按键上输入你的药单编号,然后里面的这个自动化程序如何做呢?用一个“管道”将一个“拣药”的窗口和你取药的窗口,用一个管子(pipe)一连接,自动化程序就不管这件事情了 。“拣药程序”按药单拣了药之后,直接通过之前建立的“管道”将药送到你的面前 。是不是大大简化了整个过程?