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 发生了很多变化,所以我想知道现在是否有更好/更快的方法?
示例没有正确的错误处理和检查文件包含不可分割的字节数的情况。
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)