Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • 搜索未来:SEO与GEO双引擎实战手册
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • Rust 开发入门
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • 搜索未来:SEO与GEO双引擎实战手册
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • Rust 开发入门
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 11.2 文件操作与I/O

11.2 文件操作与I/O

文件操作与输入/输出(I/O)是任何实用程序的基础。Rust 的标准库提供了强大且安全的文件处理能力,其设计理念延续了 Rust 一贯的安全和零成本抽象原则。本章将深入探讨如何在 Rust 中进行文件读写、处理路径以及使用标准 I/O 流。

11.2.1 文件路径与 Path

在 Rust 中,文件路径操作主要依赖于 std::path::Path 和 std::path::PathBuf 类型。Path 是一个不可变的切片类型,而 PathBuf 是可变的、拥有所有权的路径类型。

use std::path::Path;

fn main() {
    let path = Path::new("example.txt");
    
    // 检查文件是否存在
    println!("文件是否存在: {}", path.exists());
    
    // 获取文件扩展名
    if let Some(ext) = path.extension() {
        println!("文件扩展名: {:?}", ext);
    }
    
    // 获取父目录
    if let Some(parent) = path.parent() {
        println!("父目录: {:?}", parent);
    }
}

11.2.2 读取文件内容

Rust 提供了多种读取文件内容的方式,最常用的是 std::fs::read_to_string 和 std::fs::read。

读取文本文件

use std::fs;

fn main() -> std::io::Result<()> {
    // 读取整个文件为字符串
    let content = fs::read_to_string("hello.txt")?;
    println!("文件内容:\n{}", content);
    Ok(())
}

读取二进制文件

use std::fs;

fn main() -> std::io::Result<()> {
    // 读取整个文件为字节向量
    let data = fs::read("image.png")?;
    println!("文件大小: {} 字节", data.len());
    Ok(())
}

11.2.3 写入文件

写入文件同样简单直接,std::fs::write 可以一次性写入数据。

use std::fs;

fn main() -> std::io::Result<()> {
    // 写入字符串到文件
    fs::write("output.txt", "Hello, Rust I/O!")?;
    
    // 写入字节数据
    let bytes = vec![0x48, 0x65, 0x6c, 0x6c, 0x6f]; // "Hello" 的 ASCII 码
    fs::write("binary.dat", bytes)?;
    
    Ok(())
}

11.2.4 使用 File 结构体进行精细控制

对于需要更精细控制的操作,如追加写入或随机访问,可以使用 std::fs::File 结构体。

打开与创建文件

use std::fs::{File, OpenOptions};
use std::io::Write;

fn main() -> std::io::Result<()> {
    // 创建新文件(如果存在则覆盖)
    let mut file = File::create("new_file.txt")?;
    file.write_all(b"Creating a new file!")?;
    
    // 以追加模式打开文件
    let mut file = OpenOptions::new()
        .append(true)
        .open("existing_file.txt")?;
    file.write_all(b"\nAppending new content")?;
    
    Ok(())
}

读取文件内容

use std::fs::File;
use std::io::Read;

fn main() -> std::io::Result<()> {
    let mut file = File::open("data.txt")?;
    let mut content = String::new();
    
    // 读取到字符串
    file.read_to_string(&mut content)?;
    println!("读取到的内容: {}", content);
    
    // 逐行读取
    // 注意:需要重新打开文件或使用 seek 回到文件开头
    let mut file = File::open("data.txt")?;
    let mut buffer = [0u8; 1024];
    let bytes_read = file.read(&mut buffer)?;
    println!("读取了 {} 字节", bytes_read);
    
    Ok(())
}

11.2.5 目录操作

Rust 也提供了丰富的目录操作功能,包括创建、遍历和删除目录。

use std::fs;

fn main() -> std::io::Result<()> {
    // 创建目录
    fs::create_dir("my_directory")?;
    
    // 递归创建目录
    fs::create_dir_all("path/to/nested/directory")?;
    
    // 读取目录内容
    for entry in fs::read_dir(".")? {
        let entry = entry?;
        let path = entry.path();
        if path.is_dir() {
            println!("目录: {:?}", path);
        } else if path.is_file() {
            println!("文件: {:?}", path);
        }
    }
    
    // 删除目录(目录必须为空)
    fs::remove_dir("my_directory")?;
    
    // 递归删除目录
    fs::remove_dir_all("path")?;
    
    Ok(())
}

11.2.6 标准 I/O 流

Rust 的标准 I/O 流(stdin、stdout、stderr)提供了与命令行交互的能力。

use std::io::{self, Write, BufRead};

fn main() -> io::Result<()> {
    // 读取用户输入
    let mut input = String::new();
    println!("请输入你的名字:");
    io::stdin().read_line(&mut input)?;
    println!("你好, {}!", input.trim());
    
    // 使用 BufRead 逐行读取
    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let line = line?;
        if line == "quit" {
            break;
        }
        println!("你输入了: {}", line);
    }
    
    // 写入到 stdout
    writeln!(io::stdout(), "这是标准输出")?;
    
    // 写入到 stderr
    writeln!(io::stderr(), "这是错误输出")?;
    
    Ok(())
}

11.2.7 文件 I/O 最佳实践

使用 BufReader 和 BufWriter 提高性能

对于大文件的读取和写入,使用缓冲读写器可以显著提升性能。

use std::fs::File;
use std::io::{BufReader, BufWriter, Write, BufRead};

fn main() -> std::io::Result<()> {
    // 带缓冲的读取
    let file = File::open("large_file.txt")?;
    let reader = BufReader::new(file);
    for line in reader.lines() {
        let line = line?;
        // 处理每一行
    }
    
    // 带缓冲的写入
    let file = File::create("output.txt")?;
    let mut writer = BufWriter::new(file);
    writer.write_all(b"Buffered write operation")?;
    
    Ok(())
}

错误处理

始终使用 Result 类型处理文件操作,因为文件 I/O 极易出错。

use std::fs::File;
use std::io::{self, Read};

fn read_config_file(path: &str) -> Result<String, io::Error> {
    let mut file = File::open(path)?;
    let mut content = String::new();
    file.read_to_string(&mut content)?;
    Ok(content)
}

fn main() {
    match read_config_file("config.toml") {
        Ok(content) => println!("配置内容: {}", content),
        Err(e) => eprintln!("读取配置文件失败: {}", e),
    }
}

通过掌握这些文件操作与 I/O 技术,你将能够在 Rust 中高效地处理各种数据持久化和输入输出需求。记住,Rust 的所有权系统和类型安全特性同样适用于文件操作,确保你的程序在运行时不会出现内存安全问题。

Last Updated:: 5/9/26, 3:13 PM