由于Rust比较新,我看到了很多阅读和编写文件的方法.许多人为他们的博客提出了非常混乱的片段,我发现的99%的例子(即使在Stack Overflow上)来自不稳定的构建,不再有效.现在Rust是稳定的,什么是简单,可读,非恐慌的读取或写入文件片段?
这是我最接近阅读文本文件的东西,但它仍然没有编译,即使我很确定我已经包含了我应该拥有的一切.这是基于我在所有地方的Google+上发现的一个片段,我唯一改变的是旧BufferedReader的现在只是BufReader:
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
fn main() {
let path = Path::new("./textfile");
let mut file = BufReader::new(File::open(&path));
for line in file.lines() {
println!("{}", line);
}
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨:
error: the trait bound `std::result::Result<std::fs::File, std::io::Error>: std::io::Read` is not satisfied [--explain E0277]
--> src/main.rs:7:20
|>
7 |> let mut file = BufReader::new(File::open(&path));
|> ^^^^^^^^^^^^^^
note: required by `std::io::BufReader::new`
error: no method named `lines` found for type `std::io::BufReader<std::result::Result<std::fs::File, std::io::Error>>` in the current scope
--> src/main.rs:8:22
|> …Run Code Online (Sandbox Code Playgroud) 我有一个未知大小的字节缓冲区,我想创建一个指向缓冲区开头内存的本地struct变量.按照我在C中所做的,我在Rust中尝试了很多不同的东西并且不断出错.这是我最近的尝试:
use std::mem::{transmute, size_of};
#[repr(C, packed)]
struct my_struct {
foo: u16,
bar: u8,
}
fn main() {
let v: Vec<u8> = vec![1, 2, 3];
let buffer = v.as_slice();
let s: my_struct = unsafe { transmute(buffer[..size_of::<my_struct>()]) };
}
Run Code Online (Sandbox Code Playgroud)
我收到以下消息的错误:
std::marker::Sized没有实现[u8][u8]在编译时没有已知的常量std::mem::transmute我已阅读如何从Rust中的文件读取结构?,但std::slice::raw::mut_buf_as_slice已被弃用,因此我想重新提出这个问题.
我想读一个struct utmp来自/var/run/utmp,我尝试了以下代码:
fn read_utmp() -> Utmp {
let mut reader = BufReader::new(File::open("/var/run/utmp").unwrap());
let mut ut = vec![];
let size = mem::size_of::<Utmp>();
reader.take(size as u64).read_to_end(&mut ut);
unsafe {
std::mem::transmute(ut)
}
}
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,编译器投诉:
错误:使用不同大小的类型调用transmute:std :: vec :: Vec(192位)到Utmp(3056位)[E0512]
我怎么能这样做?
我需要分配一个缓冲区来读取 a File,但是这个缓冲区必须与缓存行的大小(64 字节)对齐。我正在寻找一个有点像这样的功能Vec:
pub fn with_capacity_and_aligned(capacity: usize, alignment: u8) -> Vec<T>
Run Code Online (Sandbox Code Playgroud)
这将为我提供所需的 64 字节对齐。这显然不存在,但可能有一些我不知道的等价物(即“黑客”)。
所以,当我使用这个函数(它会给我所需的对齐)时,我可以安全地编写这段代码:
#[repr(C)]
struct Header {
magic: u32,
some_data1: u32,
some_data2: u64,
}
let cache_line_size = 64; // bytes
let buffer: Vec<u8> = Vec::<u8>::with_capacity_and_alignment(some_size, cache_line_size);
match file.read_to_end(&mut buffer) {
Ok(_) => {
let header: Header = {
// and since the buffer is aligned to 64 bytes, I wont get any SEGFAULT
unsafe { transmute(buffer[0..(size_of::<Header>())]) }
};
}
}
Run Code Online (Sandbox Code Playgroud)
并且不会因为对齐问题(例如启动指令)而出现任何恐慌。