如何从Rust中的二进制文件中读取C结构?

时间:2016-07-12 17:00:40

标签: serialization io rust

我已阅读How to read a struct from file in Rust?,但std::slice::raw::mut_buf_as_slice已被弃用,因此我想重新提出这个问题。

我想从struct utmp阅读/var/run/utmp,我尝试了以下代码:

fn read_utmp() -> Utmp {
    let mut reader = BufReader::new(File::open("/var/run/utmp").unwrap());
    let mut ut = vec![];
    let size = mem::size_of::<Utmp>();
    reader.take(size as u64).read_to_end(&mut ut);
    unsafe {
        std::mem::transmute(ut)
    }
}

正如预期的那样,编译器投诉:

  

错误:使用不同大小的类型调用transmute:std :: vec :: Vec(192位)到Utmp(3056位)[E0512]

我怎么能这样做?

1 个答案:

答案 0 :(得分:4)

我认为Cursor c = db.rawQuery("SELECT * FROM "+ TABLE_DAYS ,null); 已替换为slice::from_raw_parts_mut

注意以下代码未考虑任何endiannesspadding问题,旨在与POD types一起使用。在这种情况下,raw::mut_buf_as_slice应该是安全的。

这是一个可以从文件中读取(pod类型)结构的函数:

struct utmp

如果要从utmp文件中读取所有utmp结构,可以多次执行use std::io::{self, BufReader, Read}; use std::fs::{self, File}; use std::path::Path; use std::slice; fn read_struct<T, R: Read>(mut read: R) -> io::Result<T> { let num_bytes = ::std::mem::size_of::<T>(); unsafe { let mut s = ::std::mem::uninitialized(); let mut buffer = slice::from_raw_parts_mut(&mut s as *mut T as *mut u8, num_bytes); match read.read_exact(buffer) { Ok(()) => Ok(s), Err(e) => { ::std::mem::forget(s); Err(e) } } } } // use // read_struct::<Utmp>(reader) 或一次读取所有文件:

read_struct