【问题标题】:Idiomatic way to parse binary data into primitive types将二进制数据解析为原始类型的惯用方法
【发布时间】:2015-05-06 08:54:06
【问题描述】:

我编写了以下方法来使用GzDecoder from the Flate2 library从压缩文件中解析二进制数据

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 时。这一切对我来说都非常不雅,我相信有更好的方法来做到这一点。我很高兴听到有关如何清理此代码的任何建议。

【问题讨论】:

标签: rust


【解决方案1】:

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

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

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

我推荐byteorder 库。使用它,您可以为所需的原语调用特定方法:

reader.read_u16::<LittleEndian>()

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

您可能还想研究像 rustc-serializeserde 这样的序列化库,看看它们是否适合您的任何用例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-14
    • 2014-10-30
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多