Appearance
Buffer
Buffer 用来表示 Node 中的二进制,表现出来的是 16 进制,代表的是内存,不能随便调整大小。
js
const b1 = Buffer.alloc(10) // Node 中的最小单位是字节
const b1 = Buffer.allocUnsafe(10) // 从内存中拿 10 个字节,不一定都是 0。
const b2 = Buffer.from([1, 2, 10, 22, 256]) // 超过 255 会取余
const b3 = Buffer.from('一') // 一个汉字三个字节
console.log(b1.length) // 字节长度,长度不能改变。Buffer 可以和字符串互相转化
js
Buffer.from('foo').toString('base64') // 转化成 base64 格式
// 解决 Buffer 不支持的编码,如 GBK
const iconvLite = require('iconv-lite')
const buffer = fs.readFileSync(path.resolve(__dirname, 'gbk.txt')) // 二进制
buffer.toString('gbk') // 报错
buffer.toString() // 乱码
iconvLite.decode(content, 'gbk') // 二进制转 GBKBuffer.prototype.copy
js
const b1 = Buffer.from('foo')
const b2 = Buffer.from('bar')
// 声明一个更大的 Buffer,将多个 Buffer 拷贝上去。
const b3 = Buffer.alloc(6)
b1.copy(b3, 0, 0, 3) // 数字分别表示拷贝到新 Buffer 的位置,源的开始和结束。
b2.copy(b3, 3, 0, 3)
// 不会影响新的 Buffer,因为是两块内存。
b1[0] = 10
console.log(b3.toString()) // foobar
Buffer.prorotype.copy = function (
targetBuffer,
targetStart,
sourceStart = 0,
sourceEnd = this.length
) {
for (let i = sourceStart; i < sourceEnd; i++) {
targetBuffer[targetStart++] = this[i]
}
}Buffer.prototype.slice
js
const b1 = Buffer.from('foo')
console.log(b1.slice(1).toString()) // ooBuffer.prototype.indexOf
第一次出现在第几个字节
js
const buffer = Buffer.from('foofoo')
const index1 = buffer.indexOf('f')
const index2 = buffer.indexOf('f', 2) // 从第 2 个字节开始找
console.log(index1, index2) // 0 3实现 Buffer.prototype.split
js
Buffer.prototype.split = function (s) {
const buffer = this
const res = []
const length = Buffer.from(s).length
let prevIndex = 0
let currentIndex = buffer.indexOf(s)
if (currentIndex === -1) {
res.push(buffer)
return res
}
// foofoo
while (currentIndex !== -1) {
const token = buffer.slice(prevIndex, currentIndex)
if (token.length) {
res.push(token)
}
prevIndex = currentIndex + length
currentIndex = buffer.indexOf(s, prevIndex)
}
if (prevIndex < buffer.length) {
res.push(buffer.slice(prevIndex))
}
return res
}
const buffer = Buffer.from('foofoo')
const segments = buffer.split('of')
console.log(segments)Buffer.slice
js
const b1 = Buffer.from('foo')
const sliced = b1.slice(0, 1) // 从内存地址中截取,会对源 Buffer 也造成影响。
sliced[0] = 10
console.log(b1.toString()) // oo
const ary = [[1, 2, 3], [4, 5, 6]]
const slicedAry = ary.slice(0, 1)
slicedAry[0][0] = 100
console.log(ary) // [ [ 100, 2, 3 ], [ 4, 5, 6 ] ]Buffer.isBuffer
js
const buffer = Buffer.from('foo')
console.log(Buffer.isBuffer(buffer)) // true
Buffer.isBuffer = function (v) {
return v instanceof Buffer
}Buffer.concat
js
const b1 = Buffer.from('foo')
const b2 = Buffer.from('bar')
const b3 = Buffer.concat([b1, b2], 6)
console.log(b3.toString()) // foobar
Buffer.concat = function (bufferList, length) {
if (length === undefined) {
length = 0
for (let i = 0, l = bufferList.length; i < l; i++) {
length += bufferList[i].length
}
}
const buffer = Buffer.alloc(length)
for (let i = 0, l = bufferList.length, prev = 0; i < l; i++) {
const b = bufferList[i]
const length = b.length
b.copy(buffer, prev)
prev += length
}
return buffer
}