首页 文章

用于将二进制数据解析为基本类型的惯用方法

提问于
浏览
6

我编写了以下方法来使用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 . 这一切对我来说都是非常不优雅的,而且我是一个更好的方法 . 我很高兴听到有关如何清理此代码的任何建议 .

1 回答

  • 7

    您的代码允许任何可复制的 T ,而不仅仅是原语 . 这意味着您可以尝试使用引用解析某些内容,这可能不是您想要的:

    #[derive(Copy)]
    struct Foo(&str);
    

    但是,代码的一般草图是我所期望的 . 您需要一个临时位置来存储一些数据,然后您必须将该数据转换为适当的原语(可能涉及终端问题) .

    我推荐byteorder库 . 有了它,您可以调用所需的基元的特定方法:

    reader.read_u16::<LittleEndian>()
    

    由于这些方法知道所需的大小,因此它们可以堆栈分配一个数组以用作临时缓冲区,这可能比堆分配更有效 . 另外,我建议更改代码以接受具有 Read 特征的通用对象,而不是特定的 GzDecoder .

    您可能还想查看序列化库,如rustc-serializeserde,以查看它们是否适合您的任何用例 .

相关问题