Hi. i am fool.
i try iterate recursive in folders:
I need understand, I don't know whether to use String or Path? or know its methods.
folder contain -> folder1 and folder2.
use std::path::Path;
fn main() {
let root = Path::new("/home/pichibw/folder/");
// iterate over root
for a in fs::read_dir(&root).unwrap() {
println!("{}", a.unwrap().path().display());
for b in fs::read_dir(&.unwrap().path().display()).unwrap() {
println!("{}", b.unwrap().path().display());
} // end for b
} //end for a
}
OUTPUT ERROR:
for b in fs::read_dir(&a.unwrap().path().display()).unwrap() {
the trait AsRef<Path>
is not implemented for std::pat h::Display<'_>
required by a bound introduced by this call
Follow the types and documentation.
pub fn read_dir<P: AsRef<Path>>(path: P) -> Result<ReadDir>
ReadDir
says:
This iterator is returned from the read_dir
function of this module and will yield instances of io::Result<DirEntry>
. Through a DirEntry
information like the entry’s path and possibly other metadata can be learned.
And from there we can see that path
returns a PathBuf
.
PathBuf
implements AsRef<Path>
so you should keep that around for your second read_dir
. The Display<'_>
returned by Path::display
is just for printing, because operating system paths aren't necessarily valid UTF8 or any other encoding.
There is one more wrinkle that I can't blame anyone for tripping over. The libs team made the questionable decision of returning various io::ErrorKind
errors without stabilizing them. As such there is no proper way on stable to be sure your read_dir
failed due to calling it on something that's not a directory. Instead, you're going to have to do a racy check either before attempting the read_dir
or after attempting it and getting an error.
You can use DirEntry::file_type
to get a FileType
for testing.
Here's what it looks like after putting all that together.
You may also be interested in the walkdir
crate.
1 Like
How to convert ReadDir structs in String or Path ??
Thanks.
&Path
is to PathBuf
as &str
is to String
. So:
let entry = a.unwrap();
let path_buf: PathBuf = a.path();
let path: &Path = &*path_buf;
Not all PathBuf
s (or &Path
s) can be losslessly turned into String
s. Sometimes you can lossfully convert, but in your program, you want to stick with PathBuf
/ &Path
because if you lossfully convert the PathBuf
, your attempt to read_dir
on it won't succeed (or might even succeed but on a different file entry that corresponds to the lossfully converted name).
1 Like
For the moment, this piece works for me.
Thanks a lot.
for a in fs::read_dir(dir)? {
let path = a?.path();
// Get path string.
let path_str = path.to_str().unwrap();
let category = Path::new(path_str);
//println!("{}", category.display());
for b in fs::read_dir(category)? {
println!("{:?}", b);
} // end for b
} //end for a