我可以看到,在 Rust 中,我可以通过以下方式将文件读取为字节数组:
File::open(&Path::new("fid")).read_to_end();
我也可以只读取一个大端或小端格式的 u32:
File::open(&Path::new("fid")).read_be_u32();
File::open(&Path::new("fid")).read_le_u32();
但据我所知,我将不得不做这样的事情(简化):
let path = Path::new("fid");
let mut file = File::open(&path);
let mut v = vec![];
for n in range(1u64, path.stat().unwrap().size/4u64){
v.push(if big {
file.read_be_u32()
} else {
file.read_le_u32()
});
}
但这太丑陋了,我只是想知道是否有更好的方法来做到这一点。
好的,所以循环中的 if
是丑陋的一大部分,所以我按照建议提升了它,新版本如下:
let path = Path::new("fid");
let mut file = File::open(&path);
let mut v = vec![];
let fun = if big {
||->IoResult<u32>{file.read_be_u32()}
} else {
||->IoResult<u32>{file.read_le_u32()}
};
for n in range(1u64, path.stat().unwrap().size/4u64){
v.push(fun());
}
了解了 range_step
和使用 _
作为索引,所以现在我剩下:
let path = Path::new("fid");
let mut file = File::open(&path);
let mut v = vec![];
let fun = if big {
||->IoResult<u32>{file.read_be_u32()}
} else {
||->IoResult<u32>{file.read_le_u32()}
};
for _ in range_step(0u64, path.stat().unwrap().size,4u64){
v.push(fun().unwrap());
}
还有什么建议吗?这看起来已经好多了。
最佳答案
此解决方案将整个文件读入缓冲区,然后创建缓冲区的单词 View ,然后将这些单词映射到向量中,转换字节顺序。 collect()
避免了增长可变向量的所有重新分配。您还可以 mmap
文件而不是将其读入缓冲区。
use std::io::File;
use std::num::{Int, Num};
fn from_bytes<'a, T: Num>(buf: &'a [u8]) -> &'a [T] {
unsafe {
std::mem::transmute(std::raw::Slice {
data: buf.as_ptr(),
len: buf.len() / std::mem::size_of::<T>()
})
}
}
fn main() {
let buf = File::open(&Path::new("fid")).read_to_end().unwrap();
let words: &[u32] = from_bytes(buf.as_slice());
let big = true;
let v: Vec<u32> = words.iter().map(if big {
|&n| { Int::from_be(n) }
} else {
|&n| { Int::from_le(n) }
}).collect();
println!("{}", v);
}
关于io - 我应该如何阅读有关字节序的文件内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26287470/