// 创建一个空的 `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 本身实现了 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

    分类:
    后端
    标签: