我编写了以下方法,使用GzDecoder from the Flate2 library
解析gzip压缩文件中的二进制数据fn read_primitive<T: Copy>(reader: &mut GzDecoder<File>) -> std::io::Result<T>
{
let sz = mem::size_of::<T>();
let mut vec = Vec::<u8>::with_capacity(sz);
let ret: T;
unsafe{
vec.set_len(sz);
let mut s = &mut vec[..];
try!(reader.read(&mut s));
let ptr :*const u8 = s.as_ptr();
ret = *(ptr as *const T)
}
Ok(ret)
}
它有效,但我对代码并不是特别满意,尤其是使用虚拟向量和临时变量ptr
时。这对我来说都是非常不优雅的,我相信有更好的方法可以做到这一点。我很高兴听到有关如何清理此代码的任何建议。
答案 0 :(得分:7)
您的代码允许任何可复制T
,而不仅仅是原语。这意味着您可以尝试使用引用来解析某些内容,这可能不是您想要的内容:
#[derive(Copy)]
struct Foo(&str);
然而,您的代码的一般草图是我所期望的。您需要一个临时的位置来存储一些数据,然后您必须将该数据转换为适当的原语(可能涉及终端问题)。
我推荐byteorder库。有了它,您可以调用所需原语的特定方法:
reader.read_u16::<LittleEndian>()
由于这些方法知道所需的大小,因此它们可以堆栈分配一个数组以用作临时缓冲区,这可能比堆分配更有效。此外,我建议您更改代码以接受具有Read
特征的通用对象,而不是特定的GzDecoder
。
您可能还想查看序列化库,例如rustc-serialize或serde,看看它们是否适合您的任何用例。