7个不稳定版本 (3个重大变更)
使用旧的Rust 2015
0.4.1 | 2017年5月21日 |
---|---|
0.4.0 | 2017年5月21日 |
0.3.1 | 2017年4月1日 |
0.2.0 | 2017年3月20日 |
0.1.1 | 2017年3月19日 |
#1549 in 编码
每月下载量 624次
用于 7 个crate (4 个直接使用)
47KB
958 行
bytepack
bytepack
是一个简单的crate,它扩展了 std::io
API,能够读取和写入任何数据类型的内存表示形式。它被视为 std::io::Read
和 std::io::Write
特征的泛化,但操作的是泛型参数 T
而不是 u8
。这个crate通过无拷贝(除了一个明确标记的案例)并提供了读取和写入数组的方法,专注于性能。
bytepack
提供了三个特征家族,允许不同的字节序控制。 Unpacker
和 Packer
在操作系统的字节序中读取和写入数据。 LEUnpacker
和 LEPacker
总是在小端字节序中读取和写入数据,而 BEUnpacker
和 BEPacker
在大端字节序中执行相同的操作。它们都符合相同的API,该API是从 std::io
复制的。这意味着只需将不同的特征引入作用域,就可以在不同的字节序之间切换。
因为 bytepack
不是一个序列化库,它不能直接从Reader或Writer读取和写入像 Vec
、Rc
等复杂类型。实际上,这些类型并不直接包含打包在内部的数据,而是持有对它的引用或指针。为了识别持有其数据“打包”在一起的数据类型,使用 Packed
特征。此外,它还提供了一种原地字节序切换方法。可以为被认为安全读取和写入的数据类型实现此特征。在 bytepack_derive
crate 中还实现了仅由实现 Packed
的类型组成的结构的自动派生。
示例
这里有两个函数,可以将 Vec<f32>
序列化和反序列化
extern crate bytepack;
use std::fs::File;
use std::iter::repeat;
use bytepack::{LEPacker, LEUnpacker};
fn write_samples(file: &str, samples: &Vec<f32>) {
let mut file = File::create(file).unwrap();
file.pack(samples.len() as u32).unwrap();
file.pack_all(&samples[..]).unwrap();
}
fn read_samples(file: &str) -> Vec<f32> {
let mut file = File::open(file).unwrap();
let num_samples : u32 = file.unpack().unwrap();
let mut samples : Vec<f32> = repeat(0f32).take(num_samples as usize).collect();
file.unpack_exact(&mut samples[..]).unwrap();
return samples;
}
得益于 Packed
特质的泛型性,我们可以使之前的函数泛型化
extern crate bytepack;
use std::fs::File;
use bytepack::{LEPacker, Packed};
fn write_vec<T: Packed + Clone>(file: &str, samples: &Vec<T>) {
let mut file = File::create(file).unwrap();
file.pack(samples.len() as u32).unwrap();
file.pack_all(&samples[..]).unwrap();
}
因为我们可以为我们自己的结构体派生 Packed,所以我们可以使用我们自己的类型
extern crate bytepack;
#[macro_use]
extern crate bytepack_derive;
use std::fs::File;
use bytepack::{LEPacker, Packed};
#[derive(Packed, Clone)]
struct Vertex<T: Packed> {
x: T,
y: T,
z: T
}
fn write_vec<T: Packed + Clone>(file: &str, samples: &Vec<T>) {
let mut file = File::create(file).unwrap();
file.pack(samples.len() as u32).unwrap();
file.pack_all(&samples[..]).unwrap();
}
fn main() {
let square : Vec<Vertex<f32>> = vec![
Vertex{x: 0.0, y: 0.0, z: 0.0},
Vertex{x: 1.0, y: 0.0, z: 0.0},
Vertex{x: 1.0, y: 1.0, z: 0.0},
Vertex{x: 0.0, y: 1.0, z: 0.0},
];
write_vec("square.raw", &square);
}
依赖项
~1.5MB
~41K SLoC