js实现bytebuffer
实现 ByteBuffer 的基本结构
在 JavaScript 中实现 ByteBuffer 需要处理二进制数据的存储和操作。可以使用 ArrayBuffer 和 DataView 作为基础。
class ByteBuffer {
constructor(initialCapacity = 1024) {
this.buffer = new ArrayBuffer(initialCapacity);
this.view = new DataView(this.buffer);
this.position = 0;
this.capacity = initialCapacity;
}
}
动态扩容机制
当写入数据超过当前容量时自动扩展缓冲区大小。
ensureCapacity(requiredCapacity) {
if (requiredCapacity <= this.capacity) return;
let newCapacity = this.capacity * 2;
while (newCapacity < requiredCapacity) {
newCapacity *= 2;
}
const newBuffer = new ArrayBuffer(newCapacity);
new Uint8Array(newBuffer).set(new Uint8Array(this.buffer));
this.buffer = newBuffer;
this.view = new DataView(this.buffer);
this.capacity = newCapacity;
}
基本写入方法
实现常见数据类型的写入操作。
putInt8(value) {
this.ensureCapacity(this.position + 1);
this.view.setInt8(this.position, value);
this.position += 1;
}
putInt16(value) {
this.ensureCapacity(this.position + 2);
this.view.setInt16(this.position, value);
this.position += 2;
}
putInt32(value) {
this.ensureCapacity(this.position + 4);
this.view.setInt32(this.position, value);
this.position += 4;
}
putFloat32(value) {
this.ensureCapacity(this.position + 4);
this.view.setFloat32(this.position, value);
this.position += 4;
}
putFloat64(value) {
this.ensureCapacity(this.position + 8);
this.view.setFloat64(this.position, value);
this.position += 8;
}
基本读取方法
实现常见数据类型的读取操作。
getInt8() {
const value = this.view.getInt8(this.position);
this.position += 1;
return value;
}
getInt16() {
const value = this.view.getInt16(this.position);
this.position += 2;
return value;
}
getInt32() {
const value = this.view.getInt32(this.position);
this.position += 4;
return value;
}
getFloat32() {
const value = this.view.getFloat32(this.position);
this.position += 4;
return value;
}
getFloat64() {
const value = this.view.getFloat64(this.position);
this.position += 8;
return value;
}
字节顺序控制
添加字节序(Endianness)支持。
setEndian(littleEndian) {
this.littleEndian = littleEndian;
}
// 修改写入方法示例
putInt32(value) {
this.ensureCapacity(this.position + 4);
this.view.setInt32(this.position, value, this.littleEndian);
this.position += 4;
}
实用工具方法
添加常用的辅助功能。
reset() {
this.position = 0;
}
remaining() {
return this.capacity - this.position;
}
flip() {
const newBuffer = new ArrayBuffer(this.position);
new Uint8Array(newBuffer).set(new Uint8Array(this.buffer, 0, this.position));
this.buffer = newBuffer;
this.view = new DataView(this.buffer);
this.capacity = this.position;
this.position = 0;
}
toArray() {
return new Uint8Array(this.buffer, 0, this.position);
}
字符串处理方法
实现字符串的编码和解码。
putString(str, encoding = 'utf-8') {
const encoder = new TextEncoder(encoding);
const encoded = encoder.encode(str);
this.putInt32(encoded.length);
this.ensureCapacity(this.position + encoded.length);
new Uint8Array(this.buffer).set(encoded, this.position);
this.position += encoded.length;
}
getString(encoding = 'utf-8') {
const length = this.getInt32();
const bytes = new Uint8Array(this.buffer, this.position, length);
this.position += length;
const decoder = new TextDecoder(encoding);
return decoder.decode(bytes);
}
使用示例
const buffer = new ByteBuffer();
buffer.putInt32(123456);
buffer.putFloat32(3.14159);
buffer.putString("Hello World");
buffer.reset();
console.log(buffer.getInt32()); // 123456
console.log(buffer.getFloat32()); // 3.14159
console.log(buffer.getString()); // "Hello World"
性能优化建议
对于高性能场景,可以考虑以下优化:
- 预分配更大的初始缓冲区减少扩容次数
- 使用类型化数组(TypedArray)直接操作而非 DataView
- 实现批量写入方法减少函数调用开销
- 添加缓冲区池重用已分配的 ArrayBuffer
// 批量写入示例
putInt32Array(values) {
this.ensureCapacity(this.position + values.length * 4);
const view = new Int32Array(this.buffer, this.position, values.length);
view.set(values);
this.position += values.length * 4;
}






