如何从目录收集文件名到Vec<&str>
之类的文件中:
let paths = fs::read_dir("...")
.unwrap()
.filter_map(|e| e.ok())
.map(|e| e.path().to_str());
另外,如果文件夹不存在,如何使其返回空列表?
最佳答案
fs::read_dir
返回在 Result<DirEntry>
上进行迭代的迭代器,该迭代器公开了 DirEntry::path
方法。此方法返回 PathBuf
,它拥有包含文件名的缓冲区。
在您的原始样本中,您尝试将它们转换为&str
-这样做有两个问题:
path()
返回一个PathBuf
,您可以通过to_str()
引用它,但是您没有将PathBuf
存储在任何地方,因此编译失败,并显示以下错误:error[E0515]: cannot return value referencing temporary value
--> src/main.rs:7:18
|
7 | .map(|e| e.path().to_str());
| --------^^^^^^^^^
| |
| returns a value referencing data owned by the current function
| temporary value created here
to_str()
返回Option<str>
-如果路径包含任何非UTF8字符,则它返回None
。您最终将得到一个包含Vec
的Option<&str>
。 我建议将它们收集到
Vec<PathBuf>
中,它很简单: let paths = fs::read_dir("...")
.unwrap()
.filter_map(|e| e.ok())
.map(|e| e.path())
.collect::<Vec<_>>();
如果确实需要它们作为字符串,则可以使用: let paths = fs::read_dir("...")
.unwrap()
.filter_map(|e| e.ok())
.map(|e| e.path().to_string_lossy().into_owned())
.collect::<Vec<_>>();
to_string_lossy()
将路径转换为字符串,并用替换字符替换所有非utf8字符。它返回Cow<&str>
-可能实际上不拥有该字符串。为了确保返回拥有的字符串,我们调用into_owned()
。最后,如果文件夹不存在,则使其返回一个空列表,您可以使用如下所示的内容:
let paths : Vec<PathBuf> = match fs::read_dir("/tmsp") {
Err(e) if e.kind() == ErrorKind::NotFound => Vec::new(),
Err(e) => panic!("Unexpected Error! {:?}", e),
Ok(entries) => entries.filter_map(|e| e.ok())
.map(|e| e.path())
.collect()
};
如果发生除NotFound
之外的任何其他错误,以上示例将引起 panic -实际上,您可能会更优雅地处理该情况。
关于rust - 将文件名收集到 `Vec<str>`中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66577339/