Dart BytesBuilder
最后修改于 2025 年 4 月 4 日
Dart 中的 BytesBuilder
类提供了一种动态构建字节列表的高效方法。它对于网络协议、文件操作和二进制数据操作非常有用。
BytesBuilder
在内部管理一个可扩展的字节缓冲区,在构建字节序列时最大限度地减少内存分配。它是 Dart dart:typed_data
库的一部分。
基本定义
BytesBuilder
是一个用于构建字节列表的可变集合。它会根据需要自动增长,并提供高效添加字节的方法。
主要功能包括追加操作、长度跟踪和最终字节列表提取。它在构建大型字节序列时尤其高效。
BytesBuilder 的基本用法
此示例展示了使用 BytesBuilder 进行基本字节收集。
import 'dart:typed_data'; void main() { var builder = BytesBuilder(); builder.addByte(65); // 'A' builder.addByte(66); // 'B' builder.addByte(67); // 'C' var bytes = builder.toBytes(); print(bytes); // [65, 66, 67] }
我们创建一个 BytesBuilder,添加单个字节,然后提取最终的字节列表。当添加字节时,构建器会在内部处理内存管理。
$ dart main.dart [65, 66, 67]
添加字节列表
此示例演示了一次性添加整个字节列表。
import 'dart:typed_data'; void main() { var builder = BytesBuilder(); builder.add([1, 2, 3]); builder.add([4, 5, 6]); var bytes = builder.toBytes(); print(bytes); // [1, 2, 3, 4, 5, 6] print('Length: ${builder.length}'); // 6 }
我们添加了多个字节列表,它们会在内部进行连接。length 属性跟踪已添加的总字节数。这比逐个添加字节更有效。
$ dart main.dart [1, 2, 3, 4, 5, 6] Length: 6
构建二进制数据
此示例展示了使用 BytesBuilder 构建结构化二进制数据。
import 'dart:typed_data'; void main() { var builder = BytesBuilder(); // Add header builder.add([0xAA, 0xBB]); // Add payload length (2 bytes) builder.addByte(0); builder.addByte(5); // Add payload builder.add('Hello'.codeUnits); // Add checksum var bytes = builder.toBytes(); var checksum = bytes.fold(0, (sum, byte) => sum + byte) & 0xFF; builder.addByte(checksum); print(builder.toBytes()); }
我们使用标头、长度、有效载荷和校验和构建了一个二进制消息。BytesBuilder 高效地处理了混合的数据类型和大小。
$ dart main.dart [170, 187, 0, 5, 72, 101, 108, 108, 111, 142]
清除和重用
此示例演示了如何清除构建器以供重用。
import 'dart:typed_data'; void main() { var builder = BytesBuilder(); builder.add([1, 2, 3]); print('First build: ${builder.toBytes()}'); builder.clear(); builder.add([4, 5, 6]); print('Second build: ${builder.toBytes()}'); print('Capacity: ${builder.length}'); // 3 }
clear() 方法在重用构建器时会重置构建器,同时保留内部容量。这可以避免在重新构建相似大小的字节序列时进行重新分配。
$ dart main.dart First build: [1, 2, 3] Second build: [4, 5, 6] Capacity: 3
性能比较
此示例将 BytesBuilder 与手动列表连接进行了比较。
import 'dart:typed_data'; import 'dart:math'; void main() { var random = Random(); var data = List.generate(1000, (_) => random.nextInt(256)); // Using BytesBuilder var stopwatch = Stopwatch()..start(); var builder = BytesBuilder(); for (var i = 0; i < 100; i++) { builder.add(data); } var builderTime = stopwatch.elapsedMicroseconds; // Using manual concatenation stopwatch.reset(); var manual = <int>[]; for (var i = 0; i < 100; i++) { manual = [...manual, ...data]; } var manualTime = stopwatch.elapsedMicroseconds; print('BytesBuilder: $builderTime μs'); print('Manual: $manualTime μs'); }
对于大型连接,BytesBuilder 的速度明显更快,因为它最大限度地减少了内存分配和复制。手动连接会创建许多中间列表。
$ dart main.dart BytesBuilder: 1200 μs Manual: 8500 μs
最佳实践
- 预分配:对于已知大小,请使用
initialCapacity
构造函数 - 批量添加:对于多个字节,请优先使用 add 而不是 addByte
- 重用:尽可能清除并重用构建器
- 最终确定:仅在需要时调用 toBytes
来源
本教程涵盖了 Dart 的 BytesBuilder 类,并提供了实用示例,展示了基本用法、性能优势以及字节操作的常见模式。
作者
列出 所有 Dart 教程。