Buffer
什么是Buffer?
Buffer 是Node.js API 的⼀部分 主要用来处理二进制文件流和TCP流的文件缓存区 内存缓冲区 
优势:Buffer 使用堆外内存,不占用堆内存 
形式上是字节的形式,8位⼀个字节|0000 0001|0010 0011|0100 0101|0110 0111|
// Buffer 类是全局的对象,可以直接使⽤,官⽅推荐显式引⽤import { Buffer } from 'buffer';// new Buffer() 建议弃⽤Buffer.from()Buffer.from(array)Buffer.from(arrayBuffer[, byteOffset[, length]])Buffer.from(buffer)Buffer.from(object[, offsetOrEncoding[, length]])Buffer.from(string[, encoding])
Buffer.alloc(size[, fill[, encoding]])//fill:默认0, encoding默认值: 'utf8'// 创建⻓度为 10 的以零填充的缓冲区。const buf1 = Buffer.alloc(10);// 创建⻓度为 10 的缓冲区,// 使⽤值为 `1` 的字节填充。const buf2 = Buffer.alloc(10, 1);const buf3 = Buffer.allocUnsafe(10);// allocUnsafe 优劣fs.readFile(path[, options], callback)callback <Function>data <string> | <Buffer>
Buffer 的应用场景
const fs = require('fs');const path = require('path');// function to encode file data to base64 encoded stringfunction base64_encode(file) {let bitmap = fs.readFileSync(file);return Buffer.from(bitmap).toString('base64');}// function to create file from base64 encoded stringfunction base64_decode(base64str, file) {let bitmap = Buffer.from(base64str, 'base64');fs.writeFileSync(file, bitmap);console.log('******** File created from base64 encoded string********');}let base64str = base64_encode(path.join(__dirname, './play.png'));console.log(base64str);base64_decode(base64str, path.join(__dirname, 'copy.png'));
const fs = require('fs');const path = require('path');//const rs = fs.createReadStream(path.join(__dirname, '1.txt'));let data = '';rs.on('data', function (chunk) {data += chunk;});rs.on('end', function () {console.log(data);});
乱码的产生
const fs = require('fs');const path = require('path');// fs.createReadStream 的 options 中 highWaterMark默认是64kconst rs = fs.createReadStream(path.join(__dirname, '1.txt'),{ highWaterMark: 11 });let data = '';rs.on('data', function (chunk) {data += chunk;});rs.on('end', function () {console.log(data);});
解决⽅式1
// 可读流有⼀个设置编码的⽅法setEncoding():// 默认情况下没有设置字符编码,流数据返回的是 Buffer 对象。// 如果设置了字符编码,则流数据返回指定编码的字符串let rs = fs.createReadStream('test.md', {highWaterMark: 11});rs.setEncoding('utf8');
解决⽅式2
// 将⼩Buffer 拼接成⼤Buffer 对象let chunks = [];let size = 0;res.on('data', function (chunk) {chunks.push(chunk);size += chunk.length;});res.on('end', function () {let buf = Buffer.concat(chunks, size);let str = iconv.decode(buf, 'utf8');console.log(str);});
Stream
什么是Stream
nodejs Stream类型
- Readable - 可读操作。
 - Writable - 可写操作。
 - Duplex - 可读可写操作.
 Transform - 操 作被写⼊数据,然后读出结果。
pipe 管道 在管道中间对流进⾏处理
```javascript // src/pipe.js var fs = require(“fs”); var zlib = require(‘zlib’); // 压缩 input.txt ⽂件为 input.txt.gz fs.createReadStream(‘input.txt’) .pipe(zlib.createGzip()) .pipe(fs.createWriteStream(‘input.txt.gz’));
console.log(“⽂件压缩完成。”);
pipe实现原理```javascriptReadable.prototype.pipe = function(dest, options) {const src = this;src.on('data', ondata);function ondata(chunk) {const ret = dest.write(chunk);if (ret === false) {...src.pause();}}...// 保持链式调⽤return dest;};
Events 事件触发器
Node.js 的⼤部分核心API 都是围绕惯用的异步事件驱动架构构建的 
常⽤API  
emitter.on(eventName, listener)emitter.once(eventName, listener)emitter.off(eventName, listener)emitter.emit(eventName[, ...args])/*emitter.addListener(eventName, listener)emitter.removeListener(eventName, listener)*/
//简单实现上述⽅法class MyEventsEmitter{constructor(){this.events = {};}// 绑定事件on(event, cbFn){if(!this.events[event]){this.events[event] = [];}this.events[event].push(cbFn);return this;}// 解绑事件off(event, cbFn){if (this._events[type]) {// 过滤掉该事件this._events[type] =this._events[type].filter(fn => {return fn !== cbFn});}}// 只响应⼀次once(event, cbFn){const onlyonce = (...args)=> {this.off(event, cbFn);cbFn.apply(this, args);}this.on(event, onlyonce);return this;}// 触发监听事件emit(event, ...args){if (this.events[event]) {this.events[event].forEach(fn => fn.call(this, ...args));}}}
