为了学习生锈,我正在从头开始编写一个递归目录遍历程序。
use std::fs;
fn main() {
let paths = fs::read_dir("/").unwrap();
for path in paths {
println!("First: {:?}", path);
let sub_paths = fs::read_dir(path.unwrap().path());
for sub_path in sub_paths.unwrap() {
println!(" Second: {:?}", sub_path);
}
}
}这段代码的问题是,如果一个文件夹没有正确的访问权限,或者它是一个文件,那么它就存在执行。如何跳过导致类似于try...except的文件夹或文件的错误。
发布于 2020-10-04 08:28:06
备选案文1
一个可能的解决方案是使用matching。然后Ok(v)分支将类似于try块,而Err(e)分支将类似于catch块。最后,它看起来可能是(游乐场):
use std::fs;
fn main() {
match fs::read_dir("/") {
Ok(may_be_entries_vec) => {
for may_be_entry in may_be_entries_vec {
println!("First: {:?}", may_be_entry);
match may_be_entry {
Ok(entry) => {
let path = entry.path();
match fs::read_dir(&path) {
Ok(may_be_sub_entry_vec) => {
for may_be_sub_entry in may_be_sub_entry_vec {
println!(" Second: {:?}", may_be_sub_entry);
}
},
Err(e) => {
eprintln!(
"Couldn't obtain {:?} content. The error is {:?}",
path,
e
)
},
}
},
Err(_e) => {
// Ex: eprintln!("Entry is an error:{:?}", _e);
},
}
}
},
Err(e) => {
eprintln!("Couldn't obtain \"/\" content. The error is {:?}.", e);
},
}
}选项2
或者您可以跳过所有错误(这不是一个好选项,但仍然是一个选项) (游乐场):
use std::fs;
fn main() {
if let Ok(entries_vec) = fs::read_dir("/") {
for may_be_entry in entries_vec {
println!("First: {:?}", may_be_entry);
if let Ok(entry) = may_be_entry {
if let Ok(sub_entry_vec) = fs::read_dir(entry.path()) {
for may_be_sub_entry in sub_entry_vec {
println!(" Second: {:?}", may_be_sub_entry);
}
}
}
}
}
}选项3
或者你可能更喜欢类似功能的风格。记住,or_else的那种用途可能是值得怀疑的。如果要跳过所有错误,可以删除所有or_else调用。(游乐场):
use std::fs;
fn main() {
fs::read_dir("/")
.or_else(|e| {
eprintln!("Couldn't obtain '/' content. The error is {:?}.", e);
Err(e)
})
.iter_mut()
.flat_map(|i| i)
.for_each(|may_be_entry|{
println!("First: {:?}", may_be_entry);
may_be_entry
.or_else(|e| {
// Ex: eprintln!("Entry is an error:{:?}", e);
Err(e)
})
.iter()
.map(|e| e.path())
.map(|path| (fs::read_dir(&path), path))
.for_each(|(read_dir_result, path)|{
read_dir_result
.or_else(|e| {
eprintln!(
"Couldn't obtain '{:?}' content. The error is {:?}.",
path,
e
);
Err(e)
})
.iter_mut()
.flat_map(|i| i)
.for_each(|may_be_subentry|{
println!(" Second: {:?}", may_be_subentry);
});
});
});
}另一种可能的方法是使用运算符,从一种错误到另一种错误有一些微妙的传递。但我觉得这太过分了。
https://stackoverflow.com/questions/64192056
复制相似问题