如何在Rust中列出目录中的文件?

129

我该如何在 Rust 中列出一个目录下的所有文件?我正在寻找等价于以下 Python 代码的方法。

files = os.listdir('./')

12
std::io::fs::readdir - Levans
4个回答

247

使用std::fs::read_dir()。这里有一个示例:

use std::fs;

fn main() {
    let paths = fs::read_dir("./").unwrap();

    for path in paths {
        println!("Name: {}", path.unwrap().path().display())
    }
}

它将简单地迭代文件并打印出它们的名称。


5
哇,它甚至在 Rust 中第一次编译就成功了 ;) - JohnAllen
OP问如何列出目录中的文件,而这个答案描述了如何列出目录中的条目(可能是符号链接或其他目录)。 - Chris L. Barnes

29
你还可以使用专门为此目的设计的glob
extern crate glob;
use self::glob::glob;

let files:Vec<Path> = glob("*").collect();

11
这个方法已经不再适用了:“[u8]类型未能满足std::path::Path中的特性约束[u8]: std::marker::Sized(在std::path::Path中,对于[u8]类型,未实现std::marker::Sized特性)[E0277]。 [u8]在编译时没有已知的常量大小[E0277],因为它出现在类型std::path::Path中[E0277],而这是std::vec::Vec所需的[E0277]。 - Zelphir Kaltstahl
2
Glob 对我来说很好用,只需使用自述文件中的示例即可。 - hakunin
1
使用通配符似乎有些过度。 - Moritz

21

这可以使用glob来完成。在此游乐场上尝试一下

extern crate glob;
use glob::glob;
fn main() {
    for e in glob("../*").expect("Failed to read glob pattern") {
        println!("{}", e.unwrap().display());
    }
}

您可以查看源代码


而要递归地遍历目录,则可使用walkdir crate(Playground):

extern crate walkdir;
use walkdir::WalkDir;
fn main() {
    for e in WalkDir::new(".").into_iter().filter_map(|e| e.ok()) {
        if e.metadata().unwrap().is_file() {
            println!("{}", e.path().display());
        }
    }
}

请参阅 The Rust Cookbook目录遍历部分。


2
有时候我还是会遇到一个问题。这里有两个纯Rust的解决方案:
快速而简单 - 吞噬所有错误,最坏情况 = 空向量:
fn recurse(path: impl AsRef<Path>) -> Vec<PathBuf> {
    let Ok(entries) = read_dir(path) else { return vec![] };
    entries.flatten().flat_map(|entry| {
        let Ok(meta) = entry.metadata() else { return vec![] };
        if meta.is_dir() { return recurse(entry.path()); }
        if meta.is_file() { return vec![entry.path()]; }
        vec![]
    }).collect()
}

稍微长一点,错误传播的版本:
fn recurse_files(path: impl AsRef<Path>) -> std::io::Result<Vec<PathBuf>> {
    let mut buf = vec![];
    let entries = read_dir(path)?;

    for entry in entries {
        let entry = entry?;
        let meta = entry.metadata()?;

        if meta.is_dir() {
            let mut subdir = recurse_files(entry.path())?;
            buf.append(&mut subdir);
        }

        if meta.is_file() {
            buf.push(entry.path());
        }
    }

    Ok(buf)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接