如何在 Rust 中列出目录中的文件:分步教程

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么你需要在 Rust 中列出文件?

\n\n

想象一下:你正在用 Rust 编写一个备份工具、日志分析器或简单的文件管理器。这时,一个基础但关键的任务出现了——获取指定目录中的所有文件列表。看起来很简单?但在 Rust 中,由于其严格的类型系统和所有权机制,即使是这样一个简单的操作也隐藏着一些陷阱。

\n\n

问题 “How can I list files of a directory in Rust?” 是 Stack Overflow 上最热门的问题之一(数千次浏览!)。这并非偶然:新手经常在 std::fs::read_dir 上遇到困难,混淆迭代器,并忘记错误处理。在本教程中,我将向你展示两种可行的方法:简单方法(仅列出单个文件夹中的文件)和高级方法(递归遍历所有子目录)。开始吧!

\n\n

1. 准备工作:创建新项目

\n\n

在编写代码之前,我们先创建一个新的二进制项目。打开终端并执行:

\n\n
cargo new list_files_rs\ncd list_files_rs
\n\n

现在打开 src/main.rs——我们将在这里编写所有代码。一开始我们不需要外部依赖,只需要 Rust 标准库 std。

\n\n

2. 最简单的方法:std::fs::read_dir

\n\n

函数 std::fs::read_dir 返回一个目录条目的迭代器。每个条目都是一个 DirEntry,包含文件名、路径、类型和元数据。让我们编写一个基本示例:

\n\n
use std::fs;\nuse std::path::Path;\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    let path = Path::new("."); // 当前目录\n\n    // 读取文件夹内容\n    let entries = fs::read_dir(path)?;\n\n    for entry in entries {\n        let entry = entry?; // 解包 Result\n        let path = entry.path();\n\n        // 检查是否为文件(不是目录)\n        if path.is_file() {\n            println!("{}", path.display());\n        }\n    }\n\n    Ok(())\n}
\n\n

这里发生了什么?

\n
    \n
  • fs::read_dir(path) — 打开目录并返回 ReadDir(迭代器)。
  • \n
  • 我们遍历每个条目。每次调用 next() 返回 Result<DirEntry> — 因此需要 entry?。
  • \n
  • entry.path() 返回文件/文件夹的完整路径。
  • \n
  • 方法 path.is_file() 用于过滤掉子目录。
  • \n
\n\n

使用命令 cargo run 运行代码 — 你将看到项目根目录中的文件列表(例如 Cargo.toml、src/main.rs)。

\n\n

2.1. 按扩展名过滤

\n\n

通常我们只需要特定文件,例如仅 .rs 或 .txt 文件。添加过滤器:

\n\n
use std::fs;\nuse std::path::Path;\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    let path = Path::new(".");\n\n    for entry in fs::read_dir(path)? {\n        let entry = entry?;\n        let path = entry.path();\n\n        // 检查是否为文件且扩展名为 .rs\n        if path.is_file() && path.extension().map_or(false, |ext| ext == "rs") {\n            println!("{}", path.display());\n        }\n    }\n\n    Ok(())\n}
\n\n

使用 map_or 技巧是为了安全处理文件没有扩展名的情况 — path.extension() 返回 Option<&OsStr>。

\n\n

3. 递归遍历:深入所有子文件夹

\n\n

简单的 read_dir 不会进入子目录。如果你需要递归收集所有文件(例如,用于查找重复文件),你需要编写自己的递归函数。这是一个优雅的解决方案:

\n\n
use std::fs;\nuse std::path::Path;\n\nfn visit_dirs(dir: &Path, depth: usize) -> Result<(), Box&l                

博客

书籍推荐