# buffer 字节操作
- buffer是一个Array对象,主要用于操作字节
- 模块结构
- javascript核心模块 --- Buffer/ShowBuffer
- C++内建模块 --- node_buffer
- node在进程启动时已经加载了它,并将其放在全局对象上
# Buffer 对象
var str = "字节操作"
var buf = new Buffer(str, 'utf-8')
console.log(buf)
// <Buffer e5 ad 97 e8 8a 82 e6 93 8d e4 bd 9c>
- UTF-8编码下
中文占用3个元素
,字母和半角标点符号占用1个元素
# Buffer内存分配
- Buffer对象的内存分配不是在V8的堆内存中,而是在Node的 C++ 层面实现内存的申请
- node采用了slab分配机制 -- 动态内存管理机制
- node以
8Kb
为界限来区分Buffer是大对象还是小对象
# Buffer的转换
# 字符串转换Buffer
newBuffer(str, [encoding]) // encoding默认utf-8
// 可以不断的写入内容到Buffer对象中
buf.write(string, [offset], [length], [encoding])
# Buffer转字符串
buf.toString([encoding], [start], [end])
# Buffer的拼接
- 注意:要设置编码
setEncoding()
- Buffer 读流的时候可能没有最后部分可能没有保存完整的中文(3个元素)
var fs = require('fs')
var res = fs.createReadStream('./data/test.md')
var chunks = []
var size = 0
res.on('data', function(chunk) {
chunks.push(chunk)
size += chunk.length
})
res.on('end', function() {
var buf = Buffer.concat(chunks, size)
var str = iconv.decode(buf, 'utf8')
console.log(str)
})
- Buffer.concat()方法封装了从小Buffer对象向大对象Buffer对象的复制过程
Buffer.concat = function(list, length) {
if (!Array.isArray(list)) {
throw new Error('Usage: Buffer.concat(list, [length])')
}
if (list.length === 0) {
return new Buffer(0)
} else if (list.length === 1) {
return list[0]
}
if (typeof length !== 'number') {
length = 0
for (var i = 0; 1 < list.length; i++) {
var buf = list[i]
length += buf.length
}
}
var buffer = new Buffer(length)
var pos = 0
for (var i = 0; i < list.length; i++ ) {
var buf = list[i]
buf.copy(buffer.pos)
pos += buf.length
}
return buffer
}