Rust 文件操作 Rust 中的文件操作示例详解
花落花开99 人气:9文件路径
想要打开或者创建一个文件,首先要指定文件的路径。
Rust 中的路径操作是跨平台的,std::path
模块提供的了两个用于描述路径的类型:
PathBuf
– 具有所有权并且可被修改,类似于String
。Path
– 路径切片,类似于str
。
示例:
use std::path::Path; use std::path::PathBuf; fn main() { // 直接将一个字符串切片包装成一个路径切片 let path = Path::new("./foo/bar.txt"); // 返回上级路径,若无上级路径则返回 `None` let parent = path.parent().unwrap(); // 返回文件名(不包含文件扩展名) let file_stem = path.file_stem().unwrap(); println!( "path: {:?}, parent: {:?}, file_stem: {:?}", path, parent, file_stem ); // 创建一个空的 `PathBuf` let mut empty_path = PathBuf::new(); println!("empty_path: {:?}", empty_path); // 根据字符串切片创建 `PathBuf` let path = PathBuf::from(r"C:\windows\system32.dll"); // 添加路径 empty_path.push(r"C:\"); println!("empty_path: {:?}, path: {:?}", empty_path, path); }
文件创建和删除
Rust 的 std::fs
模块提供了一系列文件系统操作的功能。
目录创建和删除
创建目录的函数:
create_dir<P: AsRef<Path>>(path: P) -> Result<()>
– 创建一个空目录,若指定路径不存在则会返回错误create_dir_all<P: AsRef<Path>>(path: P) -> Result<()>
– 级联创建目录。
示例:
use std::fs; // 由于字符串切片实现了 `AsRef<Path>` Trait,因此函数中的参数可以直接使用字符串字面量 fn main() -> std::io::Result<()> { // 创建一个空目录 fs::create_dir("./empty")?; // 创建一个目录,若其上级目录不存在,则一同创建 fs::create_dir_all("./some/dir")?; Ok(()) }
删除目录的函数:
remove_dir<P: AsRef<Path>>(path: P) -> Result<()>
– 删除指定空目录。remove_dir_all<P: AsRef<Path>>(path: P) -> Result<()>
– 删除指定目录及其目录下的内容。
示例:
use std::fs; fn main() -> std::io::Result<()> { // 删除一个空目录 fs::remove_dir("./empty")?; // 删除指定目录及其目录下的内容,但不会删除其上级目录 fs::remove_dir_all("./some/dir")?; Ok(()) }
文件创建和删除
Rust 使用 std::fs::File
结构体与文件系统中的文件相关联,通过 std::fs::File
实例可以对文件进行读取和写入。
文件创建和删除的函数:
create<P: AsRef<Path>>(path: P) -> Result<File>
std::fs::remove_file<P: AsRef<Path>>(path: P) -> Result<()>
示例:
use std::fs; use std::fs::File; fn main() -> std::io::Result<()> { // 以只写模式打开指定文件,若文件存在则清空文件内容,若文件不存在则新建一个 let mut f = File::create("foo.txt")?; // 删除文件 fs::remove_file("foo.txt")?; Ok(()) }
文件读取和写入
std::fs::File
本身实现了 Read
和 Write
Trait,所以文件的读写非常简单。
文件打开
在读写文件之前,首先应该得到一个 File
类型实例。除了可以在创建文件时获取 File
实例,还可以使用 File
的 open
函数:
open<P: AsRef<Path>>(path: P) -> Result<File>
示例:
use std::fs::File; fn main() -> std::io::Result<()> { // 以只读模式打开指定文件,若文件不存在则返回错误 let _file = File::open("foo.txt")?; Ok(()) }
使用 create
和 open
函数获取的 File 实例是只读或者只写的,如果想要控制更多的读写选项,则需要使用 std::fs::OpenOptions
。它是一个 Builder,create
和 open
函数的底层也是这个 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(()) }
相关资料
加载全部内容