Async runtimes for Rust like tokio provide "asyncified" copies of many standard functions, including some file IO ones, which work by basically just summoning the corresponding blocking task (on a new thread?). Examples of such functions are tokio::fs::create_dir_all
, tokio::fs::read_dir
, tokio::fs::read
, ...
What's the advantage of all these functions? Why should I prefer using them over standard blocking functions in async context? If I'm .await
ing for their results, is there any gain at all?
An example would be an async web route that returns the contents of some file based on the query (using Rocket):
#[get("/foo/<query>")]
async fn foo(query: &str) -> Option<String> {
let file_path = // interpret `query` somehow and find the target file
tokio::fs::read_to_string(file_path).await.ok()
// ^ Why not just `std::fs::read_to_string(file_path).ok()`?
}
I understand the gains of async/.await
for socket IO or delayed tasks (with thread sleep), but in this case it seems pointless to me. But the opposite — this makes more complex tasks much more difficult to solve in code (working with streams when searching a file in a list of directories, for example).