Tokio (async): How to check if a file exists

I've googled around and looked at the Tokio documentation but I've not come across an answer.

I know that Tokio has reimplemented many of the standard library structs and functions to have async alternatives (E.g. tokio::fs::file::File - Rust) but is there an alternative to the Path in std::path - Rust?

TIA.

It's generally better to try whatever operation you want to perform and handle the error than to check whether the file exists explicitly. It avoids some common issues with filesystem state changing between your checks and the operation.

You can use spawn_blocking to run your file system checks on a non runtime thread. Depending on what you're doing you may not need to bother though, checking whether a file exists once shouldn't block for too long under most circumstances.

2 Likes

Thanks for the reply.

It's generally better to try whatever operation you want to perform and handle the error than to check whether the file exists explicitly

In this case, I actually want to check if the file exists and for example, would return a message of "expected file does not exist" if the file is not present.

Thanks again, I'll add a spawn_blocking thread to do this check.

What operation do you perform when the file does exist? If you proceed to open the file, overwrite it, delete it, or whatever else, I encourage you to heed @semicoleon's advice. Checking for a file's existence before accessing it is a common mistake that leads to Time-of-check Time-of-use (TOCTOU) race conditions. You can do the right thing while still returning an error message like "expected file does not exist". Checking for existence in a separate step isn't necessary in order to produce such an error message.

2 Likes

Thanks. In this scenario, I am literally checking if the file exists and displaying an appropriate message. No further file operations as a result of the check.

Agree. In the Python community, this approach is known as "EAFTP": Easier to Ask Forgiveness then Permission.

This is the implementation of the Path::exists method in the standard library:

    pub fn exists(&self) -> bool {
        fs::metadata(self).is_ok()
    }

You can do the same in your own code via tokio::fs::metadata.

2 Likes