Node.js基础 - buffer

102 阅读3分钟

buffer

  • 无需require的一个全局表变量
  • 实现nodejs下的二进制数据操作
  • v8以外的空间 不占用v8堆内存大小的内存空间
  • 内存的使用由node控制 由v8的gc回收
  • 一般配合stream流使用 充当数据缓冲区

创建 buffer

  1. alloc 创建指定字节大小的buffer
  2. allocUnsafe 创建指定大小的buffer (不安全)
  3. from 接收数据 创建buffer
alloc
const b1 = Buffer.alloc(10)
console.log(b1)
// <Buffer 00 00 00 00 00 00 00 00 00 00>
allocUnsafe
const b2 = Buffer.allocUnsafe(10)
console.log(b2)
// <Buffer f0 fe f4 2d 01 02 00 00 01 c7>
// 未回收的垃圾空间会背拿来创建 (不安全)
from
const b3 = Buffer.from('1')
console.log(b3)
// <Buffer 31>

const b4 = Buffer.from('一')
console.log(b4)
// <Buffer e4 b8 80> 中文三个字节 
console.log(b4.toString())
// 一

const b5 = Buffer.from([0xe4, 0xb8, 0x80], 'utf-8')
console.log(b5)
// <Buffer e4 b8 80>

const b6 = Buffer.from([0xe4, 0xb8, 0x80])
console.log(b6)
console.log(b6.toString())
// <Buffer e4 b8 80>

const b7 =  Buffer.from(b1)
console.log(b7)
// <Buffer 00 00 00 00 00 00 00 00 00 00>

b1[0] = 1
console.log(b1)
console.log(b7)
// <Buffer 01 00 00 00 00 00 00 00 00 00>
// <Buffer 00 00 00 00 00 00 00 00 00 00>
// 并不是相同空间 只是对老空间的拷贝 

buffer 常用实例方法

  1. fill 使用数据填充buffer
  2. write 向buffer中写入数据
  3. toString 从 buffer 中提取数据
  4. slice 截取 buffer
  5. indexOf 再 buffer 中查找数据
  6. copy 拷贝 buffer 中的数据
fill('填入数据', 插入起始下标, 插入结束下标)
let buf1 = Buffer.alloc(10)
buf1.fill('123')
console.log(buf1)
console.log(buf1.toString())
// <Buffer 31 32 33 31 32 33 31 32 33 31> 
// 1231231231 // 不能填满 自动填充 大于长度 自动截取 

buf1.fill('123', 1)
console.log(buf1)
// <Buffer 00 31 32 33 31 32 33 31 32 33>

buf1.fill('123', 1, 3)
console.log(buf1)
// <Buffer 00 31 32 00 00 00 00 00 00 00> 结束位置取不到

buf1.fill(123)
console.log(buf1)
console.log(buf1.toString())
// <Buffer 7b 7b 7b 7b 7b 7b 7b 7b 7b 7b>
// {{{{{{{{{{
write('填入数据', 插入起始下标, 插入结束下标)
let buf2 = Buffer.alloc(10)
buf2.write('123')
console.log(buf2)
console.log(buf2.toString())
// <Buffer 31 32 33 00 00 00 00 00 00 00>
// 123  // 不会自动填充

buf2.write('123', 1, 3)
console.log(buf2)
// <Buffer 00 31 32 33 00 00 00 00 00 00> 可以取到结束位置
toString (编码格式'utf-8 ...', 起始位置, 结束位置)
let buf3 = Buffer.from('演示数据')
console.log(buf3)
console.log(buf3.toString())
// <Buffer e6 bc 94 e7 a4 ba e6 95 b0 e6 8d ae>
// 演示数据

console.log(buf3.toString('utf-8', 1))
// ��示数据 // 每个中文占三个字节 
console.log(buf3.toString('utf-8', 3))
// 示数据

console.log(buf3.toString('utf-8', 3, 9))
// 示数
slice(起始位置, 结束位置)
let buf4 = Buffer.from('演示数据')
let s1 = buf4.slice()
console.log(s1)
console.log(s1.toString())
// <Buffer e6 bc 94 e7 a4 ba e6 95 b0 e6 8d ae>
// 演示数据

let s2 = buf4.slice(3, 9)
console.log(s2)
console.log(s2.toString())
// <Buffer e7 a4 ba e6 95 b0>
// 示数


let s3 = buf4.slice(-3) // 从后向前截取三个字节
console.log(s3)
console.log(s3.toString())
// <Buffer e6 8d ae>
// 据
indexOf(查找字符, 偏移量)
let buf5 = Buffer.from('演示数据,我爱前端,我爱js,我爱工资,我不爱上班')
console.log(buf5)
console.log(buf5.indexOf('爱'))
// <Buffer e6 bc 94 e7 a4 ba e6 95 b0 e6 8d ae 2c e6 88 91 e7 88 b1 e5 89 8d e7 ab af 2c e6 88 91 e7 88 b1 6a 73 2c e6 88 91 e7 88 b1 e5 b7 a5 e8 b5 84 2c e6 88 ... 13 more bytes>
// 16

console.log(buf5.indexOf('爱', 17))
// 29

console.log(buf5.indexOf('123'))
// -1
copy (拷贝到的容器, 从容器的第几个位置写入,数据拷贝的起始位置,数据拷贝的结束位置)
let c1 = Buffer.alloc(6)
let c2 = Buffer.from('演示')

c2.copy(c1) // => 将c2数据拷贝到c1
console.log(c1.toString())
console.log(c2.toString())
// 演示
// 演示

c2.copy(c1, 3, 3, 6)
console.log(c1.toString())
console.log(c2.toString())
// 示
// 演示

buffer 常用静态方法

  1. concat 将多个buffer拼接成一个新buffer
  2. isBuffer 判断档期数据是否为buffer
concat([buffer, buffer], 指定长度 合并后几个字节)
let cot1 = Buffer.from('演示')
let cot2 = Buffer.from('数据')
let cot3 = Buffer.from('123')

const cot4 =  Buffer.concat([cot1, cot2, cot3])
console.log(cot4.toString())
// 演示数据123

const cot5 =  Buffer.concat([cot1, cot2, cot3], 9)
console.log(cot5.toString())
// 演示数
isBuffer(需要判断的数据)
const is1 = Buffer.alloc(1)
console.log(Buffer.isBuffer(is1))
// true

const is2 = '123'
console.log(Buffer.isBuffer(is2))
// false

自定义 Buffer 的 split

Buffer.prototype.split = function (sep) {
    const len = Buffer.from(sep).length
    const ret = []
    let start = 0
    let offset = 0

    while(offset = this.indexOf(sep, start) !== -1) {
        ret.push(this.slice(start, offset))
        start = offset + len
    }
    ret.push(this.slice(start))
    return ret
}

const split1 = '我爱前端,我爱js,我爱工资,我不爱上班'
const split2 = split1.split('爱')
console.log(split2)
// [ '我', '前端,我', 'js,我', '工资,我不', '上班' ]