How to read a struct from a file in Rust?

前端 未结 3 622
心在旅途
心在旅途 2020-12-01 12:23

Is there a way I can read a structure directly from a file in Rust? My code is:

use std::fs::File;

struct Configuration {
    item1: u8,
    item2: u16,
            


        
3条回答
  •  鱼传尺愫
    2020-12-01 13:01

    Here you go:

    use std::io::Read;
    use std::mem;
    use std::slice;
    
    #[repr(C, packed)]
    #[derive(Debug, Copy, Clone)]
    struct Configuration {
        item1: u8,
        item2: u16,
        item3: i32,
        item4: [char; 8],
    }
    
    const CONFIG_DATA: &[u8] = &[
        0xfd, // u8
        0xb4, 0x50, // u16
        0x45, 0xcd, 0x3c, 0x15, // i32
        0x71, 0x3c, 0x87, 0xff, // char
        0xe8, 0x5d, 0x20, 0xe7, // char
        0x5f, 0x38, 0x05, 0x4a, // char
        0xc4, 0x58, 0x8f, 0xdc, // char
        0x67, 0x1d, 0xb4, 0x64, // char
        0xf2, 0xc5, 0x2c, 0x15, // char
        0xd8, 0x9a, 0xae, 0x23, // char
        0x7d, 0xce, 0x4b, 0xeb, // char
    ];
    
    fn main() {
        let mut buffer = CONFIG_DATA;
    
        let mut config: Configuration = unsafe { mem::zeroed() };
    
        let config_size = mem::size_of::();
        unsafe {
            let config_slice = slice::from_raw_parts_mut(&mut config as *mut _ as *mut u8, config_size);
            // `read_exact()` comes from `Read` impl for `&[u8]`
            buffer.read_exact(config_slice).unwrap();
        }
    
        println!("Read structure: {:#?}", config);
    }
    

    Try it here (Updated for Rust 1.38)

    You need to be careful, however, as unsafe code is, well, unsafe. After the slice::from_raw_parts_mut() invocation, there exist two mutable handles to the same data at the same time, which is a violation of Rust aliasing rules. Therefore you would want to keep the mutable slice created out of a structure for the shortest possible time. I also assume that you know about endianness issues - the code above is by no means portable, and will return different results if compiled and run on different kinds of machines (ARM vs x86, for example).

    If you can choose the format and you want a compact binary one, consider using bincode. Otherwise, if you need e.g. to parse some pre-defined binary structure, byteorder crate is the way to go.

提交回复
热议问题