什么是在Rust 1.x中读写文件的事实上的方式?

随着Rust相对较新,我看到了太多的读写文件的方式。 许多人是非常杂乱的片段,有人提出他们的博客,我发现的例子(即使在堆栈溢出)的99%是来自不稳定的构build,不再工作。 既然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); } } 

编译器抱怨:

 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 |> 8 |> for line in file.lines() { |> ^^^^^ 

总结一下,我正在寻找的是:

  • 简短
  • 可读性
  • 涵盖所有可能的错误
  • 不恐慌

您需要两个核心部分: FileRead

如果你想读一个String一切:

 use std::fs::File; use std::io::Read; fn main() { let mut data = String::new(); let mut f = File::open("/etc/hosts").expect("Unable to open file"); f.read_to_string(&mut data).expect("Unable to read string"); println!("{}", data); } 

如果你想把所有的东西都看成是一组字节:

 use std::fs::File; use std::io::Read; fn main() { let mut data = Vec::new(); let mut f = File::open("/etc/hosts").expect("Unable to open file"); f.read_to_end(&mut data).expect("Unable to read data"); println!("{}", data.len()); } 

没有一个function自己恐慌,但我使用expect因为我不知道什么样的error handling将最适合您的应用程序。

这些比为你分配一个String或者Vec假设版本稍微冗长些,但是更强大,因为你可以重用分配的数据或者追加到一个已经存在的对象。 写一个小的包装器,为你分配的对象是微不足道的,未来可能是一个符合人体工程学的添加。

写入文件是一样的,除了它总是以字节完成的。 您可以使用as_bytesString / &str转换为字节:

 use std::fs::File; use std::io::Write; fn main() { let data = "Some data!"; let mut f = File::create("/tmp/foo").expect("Unable to create file"); f.write_all(data.as_bytes()).expect("Unable to write data"); } 

我感受到来自社区的推动,使用BufReaderBufWriter而不是直接从文件中读取

缓冲读取器(或写入器)使用缓冲区来减lessIO请求的数量。 例如,一次访问磁盘读取256个字节而不是访问磁盘256次效率更高。

这就是说,我不相信读取整个文件时缓冲的读写器是有用的。 read_to_end似乎以较大的块复制数据,所以传输可能已经自然地合并成较less的IO请求。

这里有一个使用它的例子:

 use std::fs::File; use std::io::{Read, BufReader}; fn main() { let mut data = String::new(); let f = File::open("/etc/hosts").expect("Unable to open file"); let mut br = BufReader::new(f); br.read_to_string(&mut data).expect("Unable to read string"); println!("{}", data); } 

而写作:

 use std::fs::File; use std::io::{Write, BufWriter}; fn main() { let data = "Some data!"; let f = File::create("/tmp/foo").expect("Unable to create file"); let mut f = BufWriter::new(f); f.write_all(data.as_bytes()).expect("Unable to write data"); } 

当你想逐行阅读时, BufReader更有用:

 use std::fs::File; use std::io::{BufRead, BufReader}; fn main() { let f = File::open("/etc/hosts").expect("Unable to open file"); let f = BufReader::new(f); for line in f.lines() { let line = line.expect("Unable to read line"); println!("Line: {}", line); } }