Reputation: 5620
The choice seems to be between std::fs::PathExt
and std::fs::metadata
, but the latter is suggested for the time being as it is more stable. Below is the code I have been working with as it is based off the docs:
use std::fs;
pub fn path_exists(path: &str) -> bool {
let metadata = try!(fs::metadata(path));
assert!(metadata.is_file());
}
However, for some odd reason let metadata = try!(fs::metadata(path))
still requires the function to return a Result<T,E>
even though I simply want to return a boolean as shown from assert!(metadata.is_file())
.
Even though there will probably be a lot of changes to this soon enough, how would I bypass the try!()
issue?
Below is the relevant compiler error:
error[E0308]: mismatched types
--> src/main.rs:4:20
|
4 | let metadata = try!(fs::metadata(path));
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found enum `std::result::Result`
|
= note: expected type `bool`
found type `std::result::Result<_, _>`
= note: this error originates in a macro outside of the current crate
error[E0308]: mismatched types
--> src/main.rs:3:40
|
3 | pub fn path_exists(path: &str) -> bool {
| ________________________________________^
4 | | let metadata = try!(fs::metadata(path));
5 | | assert!(metadata.is_file());
6 | | }
| |_^ expected (), found bool
|
= note: expected type `()`
found type `bool`
Upvotes: 160
Views: 129555
Reputation: 24742
rust
1.81 stabilizes fs::exists
API, Which means that you can also use std::fs::exists
to check if the path exists or not.
use std::fs;
assert!(!fs::exists("does_not_exist.txt").expect("Can't check existence of file does_not_exist.txt"));
Quoting from the documentation to understand how this API differs from Path::exists
.
As opposed to the
Path::exists
method, this will only returnOk(true)
orOk(false)
if the path was verified to exist or not exist. If its existence can neither be confirmed nor denied, anErr(_)
will be propagated instead. This can be the case if e.g. listing permission is denied on one of the parent directories.
Upvotes: 6
Reputation: 1
You can use std::path::Path::is_file
:
use std::path::Path;
fn main() {
let b = Path::new("file.txt").is_file();
println!("{}", b);
}
https://doc.rust-lang.org/std/path/struct.Path.html#method.is_file
Upvotes: 17
Reputation: 431469
Note that many times you want to do something with the file, like read it. In those cases, it makes more sense to just try to open it and deal with the Result
. This eliminates a race condition between "check to see if file exists" and "open file if it exists". If all you really care about is if it exists...
Path::exists
... exists:
use std::path::Path;
fn main() {
println!("{}", Path::new("/etc/hosts").exists());
}
As mental points out, Path::exists
simply calls fs::metadata
for you:
pub fn exists(&self) -> bool { fs::metadata(self).is_ok() }
You can check if the fs::metadata
method succeeds:
use std::fs;
pub fn path_exists(path: &str) -> bool {
fs::metadata(path).is_ok()
}
fn main() {
println!("{}", path_exists("/etc/hosts"));
}
Upvotes: 238