I’m trying to read all files in a folder, as simple as that. And then filter for mp4 extensions. But I get following error:
I don’t understand, how in the following code, the e.path
statement could "create a temporary". (The whole code is obviously in them same "Ok" closure.). Is there some special stuff happening in the path() method? I could not find anything strange in the documentation.
let paths = fs::read_dir(&folder).unwrap();
for path in paths {
match path {
Ok(e) => {
let fullPath = e.path();
let extension = e
.path()
.extension()
.expect("Error getting extension")
.to_str()
.expect("Could not convert extensions to string");
println!("{}", extension)
}
_ => {}
}
I tried numerous things and stuff like .path().metadata()
does not throw this error. Only when in combination with extension()
this seems to be happening? It’s really confusing me, how a task this simple becomes so complex.
>Solution :
DirEntry::path()
returns a PathBuf
, and PathBuf::extension()
returns an Option<&OsStr>
. As you can see, the OsStr
is borrowed from the original PathBuf
/ Path
. The problem is, you’re trying to bind the extension to a variable, but you do not assign the PathBuf
that is borrowed from to a variable as well.
So the compiler is correct in saying that the PathBuf
is temporary, and will be dropped after your let extension = ...
statement, and thus extension
can not keep pointing to it.
You’re already doing the right thing – assigning another copy of that PathBuf
to fullPath
. So you can just borrow the extension from it.
Here’s a fully self-contained solution:
use std::fs;
fn main() {
let folder = "./src";
let paths = fs::read_dir(&folder).unwrap();
for path in paths {
if let Ok(e) = path {
let full_path = e.path(); // This will live at least as long as `extension`, so
// borrowing from it is fine.
let extension = full_path
.extension()
.expect("Error getting extension")
.to_str()
.expect("Could not convert extensions to string");
println!("{}", extension)
}
}
}