61个版本 (11个稳定版)
2.0.0-rc.3 | 2023年3月30日 |
---|---|
2.0.0-rc.2 | 2022年10月4日 |
2.0.0-rc.1 | 2022年3月4日 |
2.0.0-alpha.2 | 2021年12月14日 |
0.0.2 | 2014年11月24日 |
#2 in 编码
3,221,227 每月下载量
在 7,181 个crate中使用 (2,858 直接使用)
260KB
6K SLoC
Bincode
一个紧凑的编码/解码器对,使用二进制零填充编码方案。编码对象的尺寸将与在运行中的Rust程序中该对象占用的内存大小相同或更小。
除了暴露两个简单的函数(一个编码到 Vec<u8>
,另一个从 &[u8]
解码)之外,二进制编码还提供了一个Reader/Writer API,使其能够与Rust文件、网络流和 flate2-rs 压缩库等基于流的API完美配合。
API文档
野外的Bincode
- google/tarpc: Bincode用于序列化和反序列化网络RPC消息。
- servo/webrender: Bincode用于记录WebRender API调用,以便进行记录/回放式的图形调试。
- servo/ipc-channel: IPC-Channel使用Bincode通过类似通道的API在进程之间发送结构体。
- ajeetdsouza/zoxide: zoxide使用Bincode将目录数据库及其访问频率存储在磁盘上。
示例
use bincode::{config, Decode, Encode};
#[derive(Encode, Decode, PartialEq, Debug)]
struct Entity {
x: f32,
y: f32,
}
#[derive(Encode, Decode, PartialEq, Debug)]
struct World(Vec<Entity>);
fn main() {
let config = config::standard();
let world = World(vec![Entity { x: 0.0, y: 4.0 }, Entity { x: 10.0, y: 20.5 }]);
let encoded: Vec<u8> = bincode::encode_to_vec(&world, config).unwrap();
// The length of the vector is encoded as a varint u64, which in this case gets collapsed to a single byte
// See the documentation on varint for more info for that.
// The 4 floats are encoded in 4 bytes each.
assert_eq!(encoded.len(), 1 + 4 * 4);
let (decoded, len): (World, usize) = bincode::decode_from_slice(&encoded[..], config).unwrap();
assert_eq!(world, decoded);
assert_eq!(len, encoded.len()); // read all bytes
}
规范
Bincode的格式在 docs/spec.md 中指定。
常见问题解答
Bincode是否适合存储?
编码格式是稳定的,只要使用相同的配置。这应该可以保证,如果未发生重大版本变更,则后续版本仍能读取由先前版本库产生的数据。
如果使用相同的配置,Bincode 1 和 2 完全兼容。
Bincode 对字节序是无关的,这使得在不同架构之间进行交换成为可能。它也非常节省空间,因为它在输出格式中不存储元数据(如结构体字段名称),并且写入长二进制数据流时不需要任何可能增加大小的编码。
因此,Bincode 适用于存储数据。请注意,它不实现任何数据版本控制方案或文件头,因为这些功能超出了本crate的范畴。
Bincode 是否适合不信任的输入?
Bincode 尝试保护免受恶意数据的影响。有一个最大大小配置可用(Configuration::with_limit
),但在默认配置中未启用。启用它将导致预分配大小限制在内存耗尽攻击的防护范围内。
假设结构体的反序列化代码本身是安全的,反序列化任何传入的数据不会导致未定义的行为或内存问题。
在配置更改以启用最大大小限制的情况下,Bincode 可以用于不信任的输入,这样它就不会在您的应用程序中创建安全问题。恶意输入在反序列化时会失败。
Bincode 的 MSRV(最低支持的 Rust 版本)是什么?
Bincode 2.0 仍在开发中,目前还没有一个目标 MSRV。一旦 2.0 完全发布,MSRV 将被锁定。在此之后,任何对 MSRV 的更改都视为 semver 目的下的破坏性更改。
为什么 bincode 不遵守 #[repr(u8)]
?
Bincode 将枚举变体编码为 u32
。如果您担心存储大小,我们可以建议启用 Configuration::with_variable_int_encoding()
。此选项默认与 standard
配置一起启用。在这种情况下,枚举变体几乎总是编码为 u8
。
目前我们没有发现尊重 #[repr(...)]
的令人信服的理由。您最可能是在尝试与类似但不完全相同的 bincode 格式进行互操作。我们只支持我们自己的协议(规范)。
如果您确实想使用 bincode 来编码/解码不同的协议,请考虑自己实现 Encode
和 Decode
。 bincode-derive
将生成的实现输出到 target/generated/bincode/<name>_Encode.rs
和 target/generated/bincode/<name>_Decode.rs
,这应该能帮助您入门。
依赖项
~200KB