Node.js Buffer
Buffer 类是用来处理二进制数据,因为常用,所以直接放在全局变量,使用时无需 require
常用属性和方法
Buffer.from(string [, encoding])
字符串转为 Buffer。
buf.toString([encoding[, start[, end]]])
将 Buffer 转为字符串。
buf.length
buf.length:返回 内存为此 Buffer 实例所申请的字节数,并不是 Buffer 实例内容的字节数
stream
Stream 是 Node.js 提供的处理流数据的抽象接口。Node.js 中有许多对象是 stream 对象,例如 request
。在 Unix 系统中流就是一个很常见也很重要的概念,从术语上讲流是对输入输出设备的抽象。
为什么要使用流
举个例子,如果直接读取一个非常大的文件(如视频文件),一次性读取则需要占用大量内存,这对于运行在服务器的程序来说是不可取的。因此就有了流,将大文件分段读取,每次读入以少部分进行处理,这样就可以在有限的服务器资源中并发处理一定规模的请求。Node.js 设计好了 stream 流,我们只需调用其接口,不用关心底层如何实现。
Node.js 中的流类别
Node.js 内建了四类流, Readable 流、Writable 流、Duplex 流和 Transform 流的基类。另外如果觉得上述四类基类流不能满足需求,可以编写自己的扩充类流。
流是有方向的数据,按照流动方向可以分为三种流:
- 设备流向程序:readable
- 程序流向设备:writable
- 双向:duplex、transform
当一个流同时面向生产者和消费者服务的时候我们会选择 Duplex,当只是对数据做一些转换工作的时候我们便会选择使用 Tranform。
NodeJS 关于流的操作被封装到了 Stream 模块,这个模块也被多个核心模块所引用。按照 Unix 的哲学:一切皆文件,在 NodeJS 中对文件的处理多数使用流来完成:
- 普通文件
- 设备文件(stdin、stdout)
- 网络文件(http、net)
在 NodeJS 中所有的 Stream 都是 EventEmitter
的实例。
读取文件流
fs.createReadStream
方法可以创建读取文件信息的可读文件流。可读流是生产数据用来供程序消费的流。
let fileReadStream = fs.createReadStream('data.json')
fileReadStream.on('data', (chuck) => { console.log(`接收到数据:${chuck.length}`)})
可读流的事件
可读流的常用事件有:
- data 当数据传入的时候就会触发;
- error 当读取数据流时发生错误,就会触发;
- end 数据全部读取完毕后触发。
写入流信息
先创建合适的可写流,再使用 write 方法写入到文件:
let fileReadStream = fs.createReadStream('data.json')let fileWriteStream = fs.createWriteStream('data-2.json')
fileReadStream.on('data', (chuck) => { console.log(`接收到数据:${chuck.length}`) fileWriteStream.write(chuck)})
管道 pipe
pipe 管道,可以在写入流之前,进行中间环节的处理,如压缩、加密、改变编码方式等等。多个管道可以对接。
HTPP 模块
Node.js 的 HTTP API 是非常底层的。 它只涉及流处理与消息解析。 它把一个消息解析成消息头和消息主体,但不解析具体的消息头或消息主体。
http.ServerResponse 类
Response 类可以发送请求,接收请求。示例如下:
const http = require('http')
var options = { protocol: 'http:', hostname: 'api.douban.com', port: '80', method: 'GET', path: '/v2/movie/top250'}var responseData = ''var request = http.request(options, (response) => { console.log(response.statusCode) console.log(response.headers) // response.setEncoding = 'utf8' response.on('data', (chuck) => { // console.log(chuck) responseData += chuck }) response.on('end', () => { JSON.parse(responseData).subjects.map((item) => { console.log(item.title) }) })})
request.on('error', (error) => { console.log(error)})
request.end()
http.request()
返回一个http.ClientRequest
类的实例,该实例是一个可写的信息流。
创建服务器
使用createServer()
方法可以创建 www 服务器,示例如下:
'use strict'
const http = require('http')
var server = http.createServer()
server.on('request', (request, response) => { response.writeHead(200, { 'Content-Type': 'text/html' }) response.end(`<h1>hello :) </h1>`)})
server.listen(8080)
其中server
中的request
事件发生于用户请求服务时。可以通过server.listen()
方法指定 www 服务器运行端口。