Rust 中的文件操作示例详解

2022-04-15 14:47:11
目录
文件路径文件创建和删除目录创建和删除文件创建和删除文件读取和写入文件打开文件读取文件写入相关资料

文件路径

想要打开或者创建一个文件,首先要指定文件的路径。

Rust 中的路径操作是跨平台的,std::path 模块提供的了两个用于描述路径的类型:

PathBuf – 具有所有权并且可被修改,类似于 StringPath – 路径切片,类似于 str

d::fs::File;fn main() -> std::io::Result<()> { // 以只写模式打开指定文件,若文件存在则清空文件内容,若文件不存在则新建一个 let mut f = File::create("foo.txt")?; // 删除文件 fs::remove_file("foo.txt")?; Ok(())}

文件读取和写入

std::fs::File 本身实现了 ReadWrite Trait,所以文件的读写非常简单。

文件打开

在读写文件之前,首先应该得到一个 File 类型实例。除了可以在创建文件时获取 File 实例,还可以使用 Fileopen 函数:

open<P: AsRef<Path>>(path: P) -> Result<File>

示例

use std::fs::File;fn main() -> std::io::Result<()> {    // 以只读模式打开指定文件,若文件不存在则返回错误    let _file = File::open("foo.txt")?;    Ok(())}

使用 createopen 函数获取的 File 实例是只读或者只写的,如果想要控制更多的读写选项,则需要使用 std::fs::OpenOptions。它是一个 Builder,createopen 函数的底层也是这个 Builder。

使用 std::fs::OpenOptions 时,首先调用 OpenOptions::new,然后通过链式调用来设置读写选项,最后调用 OpenOptions::open 打开指定的文件。

示例

use std::fs::OpenOptions;fn main() -> std::io::Result<()> {    let _file = OpenOptions::new()        .read(true)        .write(true)        .create(true) // 新建,若文件存在则打开这个文件        .open("foo.txt")?;    let _file = OpenOptions::new()        .append(true) // 追加内容        .open("foo.txt")?;    let _file = OpenOptions::new()        .write(true)        .truncate(true) // 清空文件        .open("foo.txt");    Ok(())}

文件读取

读取文件主要用的是 std::io::Read Trait 中的函数。比如:

read(&mut self, buf: &mut [u8]) -> Result<usize> read_to_string(&mut self, buf: &mut String) -> Result<usize>

示例

use std::fs::File;use std::io;// `prelude` 模块包含通常使用的 IO Trait: `BufRead`, `Read`, `Write`, `Seek`use std::io::prelude::*;fn main() -> io::Result<()> {    let mut f = File::open("foo.txt")?;    let mut buffer = [0; 10];    // 读取文件中的前10个字节    let n = f.read(&mut buffer[..])?;    println!("The bytes: {:?}", &buffer[..n]);    // 接着读取10个字节    let n = f.read(&mut buffer[..])?;    println!("The bytes: {:?}", &buffer[..n]);    let mut f = File::open("foo.txt")?;    let mut buffer = String::new();    // 读取文件所有内容并转为字符字符串,若文件非 UTF-8 格式,则会报错    f.read_to_string(&mut buffer)?;    println!("The string: {}", buffer);    Ok(())}

另外,File 类型还实现了 std::io::Seek Trait,Seek 主要提供了一个 seek 函数,可以控制文件读取和写入的起始位置。

seek(&mut self, pos: SeekFrom) -> Result<u64>

示例

use std::fs::File;use std::io;use std::io::prelude::*;use std::io::SeekFrom;fn main() -> io::Result<()> {    let mut f = File::open("foo.txt")?;    // 将游标前移 10 个字节(游标的默认位置是 0)    f.seek(SeekFrom::Start(10))?;    // 将前 10 个字节之后的内容读取到 Buf 中    let mut buffer = String::new();    f.read_to_string(&mut buffer)?;    println!("The string: {}", buffer);    Ok(())}

除了可以设置文件读取的起点,还可以限制文件读取的长度。std::io::Read 提供了 take 函数来限制文件读取的长度。

take(self, limit: u64) -> Take<Self>

示例

use std::fs::File;use std::io;use std::io::prelude::*;fn main() -> io::Result<()> {let f = File::open("foo.txt")?;let mut buffer = [0; 10];    // 限制读取长度最多为 5 字节    let mut handle = f.take(5);    handle.read(&mut buffer)?;    println!("buffer: {:?}", buffer);    Ok(())}

文件写入

读取文件主要用的是 std::io::Write Trait 中的函数。比如:

fn write(&mut self, buf: &[u8]) -> Result<usize> – 尝试将 Buf 中的全部内容写入文件,有可能不成功。 fn flush(&mut self) -> Result<()> fn write_all(&mut self, buf: &[u8]) -> Result<()> – 持续调用 write,将 Buf 中的所有内容都写入文件。

示例

use std::fs::File;use std::io::prelude::*;fn main() -> std::io::Result<()> {    let mut buffer = File::create("foo.txt")?;    buffer.write(b"some bytes")?;    buffer.write_all(b"more bytes")?;    buffer.flush()?;    Ok(())}

相关资料

The Rust Standard Library

Rust By Example

RustPrimer