在 Rust 中读取以 f64 为单位的二进制文件

Sit*_*ito 5 file-processing rust

假设你有一个二进制文件example.bin,并且你想以 为单位读取该文件f64,即前 8 个字节给出一个浮点数,接下来的 8 个字节给出一个数字等。(假设你知道字节序)这在 Rust 中如何完成?

我知道可以用来std::fs::read("example.bin")获取 aVec<u8>数据,但是你必须做很多“体操”才能将 8 个字节始终转换为 a f64,即

fn eight_bytes_to_array(barry: &[u8]) -> &[u8; 8] {
    barry.try_into().expect("slice with incorrect length")
}

let mut file_content = std::fs::read("example.bin").expect("Could not read file!");
let nr = eight_bytes_to_array(&file_content[0..8]);
let nr = f64::from_be_bytes(*nr_dp_per_spectrum);
Run Code Online (Sandbox Code Playgroud)

我看到了这篇文章,但它是从 2015 年开始的,从那时起 Rust 发生了很多变化,所以我想知道现在是否有更好/更快的方法?

Ang*_*ros 4

示例没有正确的错误处理和检查文件包含不可分割的字节数的情况。

use std::fs::File;
use std::io::{BufReader, Read};

fn main() {
    // Using BufReader because files in std is unbuffered by default
    // And reading by 8 bytes is really bad idea.
    let mut input = BufReader::new(
        File::open("floats.bin")
        .expect("Failed to open file")
    );

    let mut floats = Vec::new();
    loop {
        use std::io::ErrorKind;
        // You may use 8 instead of `size_of` but size_of is less error-prone.
        let mut buffer = [0u8; std::mem::size_of::<f64>()];
        // Using read_exact because `read` may return less 
        // than 8 bytes even if there are bytes in the file.
        // This, however, prevents us from handling cases
        // when file size cannot be divided by 8.
        let res = input.read_exact(&mut buffer);
        match res {
            // We detect if we read until the end.
            // If there were some excess bytes after last read, they are lost.
            Err(error) if error.kind() == ErrorKind::UnexpectedEof => break,
            // Add more cases of errors you want to handle.
            _ => {}
        }
        // You should do better error-handling probably.
        // This simply panics.
        res.expect("Unexpected error during read");
        // Use `from_be_bytes` if numbers in file is big-endian
        let f = f64::from_le_bytes(buffer);
        floats.push(f);
    }
}

Run Code Online (Sandbox Code Playgroud)