好的愚蠢的noob问题,但我显然在文档中遗漏了一些东西。
我可以看到在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());
}
还有什么建议吗?这已经看起来好多了。
答案 0 :(得分:1)
此解决方案将整个文件读入缓冲区,然后创建缓冲区视图作为单词,然后将这些单词映射到向量中,转换字节顺序。 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);
}