我在这里展示的函数没有自己出现问题,但我使用 expect
,因为我不知道什么样的错误处理最适合您的应用程序。去读一下 The Rust Programming Language 的错误处理章节,以了解如何适当地处理自己程序中的故障。
Rust 1.26及以上版本
如果您不想关心底层细节,则有一行函数可用于读写操作。
将文件读取为String
use std::fs;
fn main() {
let data = fs::read_to_string("/etc/hosts").expect("Unable to read file");
println!("{}", data);
}
将文件读取为Vec<u8>
use std::fs;
fn main() {
let data = fs::read("/etc/hosts").expect("Unable to read file");
println!("{}", data.len());
}
编写文件
use std::fs;
fn main() {
let data = "Some data!";
fs::write("/tmp/foo", data).expect("Unable to write file");
}
Rust 1.0 及以后版本
这些形式比为您分配 String
或 Vec
的一行函数稍微冗长,但更强大,因为您可以重用已分配的数据或附加到现有对象。
读取数据
读取文件需要两个核心组件:File
和 Read
。
将文件读取为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);
}
将文件读取为Vec<u8>
类型
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());
}
写入文件
写入文件类似,只是我们使用Write
trait并始终写出字节。你可以使用as_bytes
将String
/ &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");
}
缓冲I/O
我感到社区对使用BufReader
和BufWriter
而不是直接从文件中读取有些推崇。
缓冲读取器(或写入器)使用缓冲区来减少 I/O 请求的数量。例如,一次访问磁盘以读取 256 字节要比访问磁盘 256 次更有效率。
话虽如此,当读取整个文件时,我不认为使用缓冲读取器/写入器会很有用。read_to_end
似乎会通过大块复制数据,所以传输可能已经自然地合并为较少的 I/O 请求。
以下是一个使用它进行读取的示例:
use std::fs::File;
use std::io::{BufReader, Read};
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::{BufWriter, Write};
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);
}
}
std::io::Read
),请注意在 Rust 中您必须 显式 导入您希望使用的特征; 因此,在这里,您缺少了一个use std::io::Read
(它可以是use std::io::{Read,BufReader}
来将两个导入合并在一起)。 - Matthieu M.