🎬 HoRain云小助手个人主页

 🔥 个人专栏: 《Linux 系列教程》《c语言教程

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

专栏介绍

专栏名称

专栏介绍

《C语言》

本专栏主要撰写C干货内容和编程技巧,让大家从底层了解C,把更多的知识由抽象到简单通俗易懂。

《网络协议》

本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘,一起解密网络协议在运行中协议的基本运行机制!

《docker容器精解篇》

全面深入解析 docker 容器,从基础到进阶,涵盖原理、操作、实践案例,助您精通 docker。

《linux系列》

本专栏主要撰写Linux干货内容,从基础到进阶,知识由抽象到简单通俗易懂,帮你从新手小白到扫地僧。

《python 系列》

本专栏着重撰写Python相关的干货内容与编程技巧,助力大家从底层去认识Python,将更多复杂的知识由抽象转化为简单易懂的内容。

《试题库》

本专栏主要是发布一些考试和练习题库(涵盖软考、HCIE、HRCE、CCNA等)

目录

⛳️ 推荐

专栏介绍

1. 文件操作 (std::fs)

2. 目录操作 (std::fs)

3. 输入输出 Traits 与标准输入输出 (std::io)

4. 缓冲读写 (BufReader& BufWriter)

5. 路径操作 (std::path)


img

Rust 的文件与 IO 操作是其标准库的重要组成部分,它提供了一套安全、高效且易于使用的 API。我会通过一个表格带你快速了解核心概念,然后详细解释重要知识点和代码示例。

模块/类型

主要用途

简单示例/形式

std::fs

文件和目录的创建、删除、读写、元数据获取等操作

File::open, fs::read_to_string, fs::write

std::io

定义 IO 操作的通用 traits(如 Read/Write),提供标准输入输出等

io::stdin(), io::stdout(), BufReader, BufWriter

std::path

路径的构建、拼接、转换(跨平台兼容)

Path, PathBuf

File

表示一个文件句柄,用于读写操作

let file = File::open("foo.txt")?;

ReadTrait​

定义从源读取字节的方法

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

WriteTrait​

定义向目标写入字节的方法

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

BufReader

缓冲读取,减少系统调用,提高读取效率(特别是多次小读取)

BufReader::new(file)

BufWriter

缓冲写入,减少系统调用,提高写入效率(特别是多次小写入)

BufWriter::new(file)

Result

用于错误处理,IO 操作几乎都返回 Result

let content = fs::read_to_string("file.txt")?;

🧱 ​​核心模块与操作详解​

1. 文件操作 (std::fs)

std::fs模块提供了丰富的文件系统操作功能。

  • ​打开文件​​:使用 File::open打开已存在的文件,使用 File::create创建新文件或覆盖已存在文件。

    use std::fs::File;
    use std::io::Read;
    
    fn main() -> std::io::Result<()> {
        // 打开文件
        let mut file = File::open("example.txt")?;
        let mut contents = String::new();
        file.read_to_string(&mut contents)?;
        println!("文件内容:{}", contents);
        Ok(())
    }
  • ​读取文件​​:对于小文件,可以一次性读取为字符串或字节向量。对于大文件,推荐使用 BufReader进行缓冲读取。

    use std::fs;
    use std::io::Result;
    
    fn main() -> Result<()> {
        // 一次性读取小文件为字符串
        let content = fs::read_to_string("example.txt")?;
        println!("{}", content);
    
        // 一次性读取小文件为字节向量(适用于二进制文件)
        let bytes = fs::read("image.png")?;
        println!("文件大小:{} 字节", bytes.len());
        Ok(())
    }
  • ​写入文件​​:对于小内容,可以使用 fs::write一次性写入。对于频繁写入或大文件,推荐使用 BufWriterFilewrite_all方法。

    use std::fs;
    use std::io::Result;
    
    fn main() -> Result<()> {
        // 一次性写入
        fs::write("output.txt", "Hello, Rust!")?;
        Ok(())
    }
  • ​追加文件​​:使用 OpenOptions来以追加模式打开文件。

    use std::fs::OpenOptions;
    use std::io::Write;
    
    fn main() -> std::io::Result<()> {
        let mut file = OpenOptions::new()
            .append(true)
            .create(true) // 如果文件不存在则创建
            .open("log.txt")?;
        file.write_all(b"New log entry\n")?;
        Ok(())
    }
  • ​删除文件​​:使用 fs::remove_file

    use std::fs;
    
    fn main() -> std::io::Result<()> {
        fs::remove_file("file_to_delete.txt")?;
        Ok(())
    }
  • ​文件元数据​​:使用 fs::metadata获取文件信息,如大小、权限、修改时间等。

    use std::fs;
    
    fn main() -> std::io::Result<()> {
        let metadata = fs::metadata("example.txt")?;
        println!("文件大小:{} 字节", metadata.len());
        println!("是否是文件:{}", metadata.is_file());
        Ok(())
    }

2. 目录操作 (std::fs)

  • ​创建目录​​:使用 fs::create_dir创建单个目录(父目录不存在会报错),使用 fs::create_dir_all递归创建目录。

    use std::fs;
    
    fn main() -> std::io::Result<()> {
        // 递归创建目录
        fs::create_dir_all("./my_dir/sub_dir")?;
        Ok(())
    }
  • ​读取目录内容​​:使用 fs::read_dir获取目录项的迭代器。

    use std::fs;
    
    fn main() -> std::io::Result<()> {
        for entry in fs::read_dir(".")? {
            let entry = entry?;
            let path = entry.path();
            if path.is_file() {
                println!("文件: {}", path.display());
            } else if path.is_dir() {
                println!("目录: {}", path.display());
            }
        }
        Ok(())
    }
  • ​删除目录​​:使用 fs::remove_dir删除空目录,使用 fs::remove_dir_all递归删除目录及其所有内容。

    use std::fs;
    
    fn main() -> std::io::Result<()> {
        // 删除空目录
        fs::remove_dir("empty_dir")?;
        // 递归删除非空目录(谨慎使用!)
        fs::remove_dir_all("dir_to_remove")?;
        Ok(())
    }

3. 输入输出 Traits 与标准输入输出 (std::io)

std::io模块定义了 ReadWrite等核心 trait,以及标准输入、输出、错误流。

  • ReadTrait​​:定义了 read, read_to_string, read_to_end等方法,用于从源读取数据。

  • WriteTrait​​:定义了 write, write_all, flush等方法,用于向目标写入数据。

  • ​标准输入输出​​:

    use std::io;
    
    fn main() -> io::Result<()> {
        let mut input = String::new();
    
        // 从标准输入读取一行
        io::stdin().read_line(&mut input)?;
        println!("你输入的是: {}", input);
    
        // 向标准输出写入一行
        io::stdout().write_all(b"Hello, stdout!\n")?;
    
        // 向标准错误写入
        io::stderr().write_all(b"An error occurred!\n")?;
        Ok(())
    }

4. 缓冲读写 (BufReader& BufWriter)

使用缓冲可以显著提高频繁读写操作的效率。

  • BufReader​:包装一个 reader,缓冲其输入,减少底层系统调用。

    use std::fs::File;
    use std::io::{BufReader, Read};
    
    fn main() -> std::io::Result<()> {
        let file = File::open("large_file.txt")?;
        let mut reader = BufReader::new(file);
        let mut buffer = String::new();
    
        // 缓冲读取
        reader.read_to_string(&mut buffer)?;
        println!("{}", buffer);
        Ok(())
    }
  • BufWriter​:包装一个 writer,缓冲其输出,多次小写入会先存入缓冲区,满时或手动刷新时一次性写入,提高效率。

    use std::fs::File;
    use std::io::{BufWriter, Write};
    
    fn main() -> std::io::Result<()> {
        let file = File::create("output.txt")?;
        let mut writer = BufWriter::new(file);
    
        // 多次写入会先缓冲
        writer.write_all(b"Hello, ")?;
        writer.write_all(b"Rust!")?;
    
        // 手动刷新确保所有数据写入磁盘
        writer.flush()?;
        Ok(())
    }

    ​注意​​:BufWriterdrop时会自动尝试刷新缓冲区,但如果刷新失败,错误可能会被忽略。为确保重要数据写入,建议手动调用 flush

5. 路径操作 (std::path)

使用 PathPathBuf来处理文件路径,它们能自动处理不同操作系统的路径分隔符差异。

  • ​路径创建与拼接​​:

    use std::path::{Path, PathBuf};
    
    fn main() {
        // 从字符串创建 Path
        let path = Path::new("./data");
    
        // 创建 PathBuf 并进行拼接
        let mut path_buf = PathBuf::from("./data");
        path_buf.push("logs");
        path_buf.push("app.log");
        println!("完整路径: {}", path_buf.display());
    
        // 使用 join 进行拼接(不修改原路径)
        let new_path = path.join("config").join("settings.toml");
        println!("拼接后的路径: {}", new_path.display());
    }
  • ​路径信息获取​​:

    use std::path::Path;
    
    fn main() {
        let path = Path::new("./src/main.rs");
    
        if path.exists() {
            println!("文件存在");
            println!("是文件: {}", path.is_file());
            println!("是目录: {}", path.is_dir());
            if let Some(filename) = path.file_name() {
                println!("文件名: {:?}", filename);
            }
        }
    }

🛠️ ​​错误处理​

Rust 的文件 IO 操作几乎都返回 Result<T, std::io::Error>,必须处理可能发生的错误。

  • ​使用 ?操作符​​:简化错误传播,非常适合在返回 Result的函数中使用。

    use std::fs::File;
    use std::io;
    
    fn read_file() -> io::Result<String> {
        let mut file = File::open("example.txt")?; // 如果出错,错误会从这里返回
        let mut content = String::new();
        file.read_to_string(&mut content)?; // 同样,出错则返回
        Ok(content)
    }
  • ​使用 match表达式​​:需要更精细地处理不同错误类型时。

    use std::fs::File;
    use std::io::{self, ErrorKind};
    
    fn main() {
        let file_result = File::open("nonexistent.txt");
    
        match file_result {
            Ok(_) => println!("文件打开成功"),
            Err(error) => match error.kind() {
                ErrorKind::NotFound => eprintln!("错误:文件未找到"),
                ErrorKind::PermissionDenied => eprintln!("错误:权限不足"),
                other_error => eprintln!("其他错误:{:?}", other_error),
            },
        }
    }
  • ​使用 unwrapexpect​:在原型开发或确定不会出错的情况,但生产代码需谨慎使用。

    let content = fs::read_to_string("file.txt").unwrap(); // 出错则 panic
    let content = fs::read_to_string("file.txt").expect("读取文件失败"); // panic 并携带自定义信息

🔧 ​​异步文件 IO​

对于高性能并发应用,Rust 的异步生态(如 tokioasync-std)提供了异步文件操作 API,可以避免阻塞线程。

📚 ​​学习建议​

  • ​多练习​​:从简单的文件读写开始,逐步尝试更复杂的操作如目录遍历、文件复制等。

  • ​查阅文档​​:Rust 标准库的 std::fsstd::io模块文档是非常好的学习资源。

  • ​错误处理​​:务必养成良好的错误处理习惯,不要轻易使用 unwrap

  • ​性能考虑​​:根据场景选择合适的读写方式(如缓冲读写)。

希望这份教程能帮助你系统地掌握 Rust 的文件与 IO 操作!

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐