Asynchronous I/O in Rust
Asynchronous I/O is essential for building non-blocking applications, such as servers, command-line tools, or GUIs. Rust provides robust support for asynchronous programming through the async/await
syntax and libraries like tokio
and async-std
.
Getting Started with Async I/O
To perform asynchronous I/O, ensure you have an asynchronous runtime installed and the appropriate dependencies. Most users choose tokio
, which is the most active and widely adopted async runtime in Rust:
Adding Dependencies
Add the following lines to your Cargo.toml
file:
[dependencies] tokio = { version = "1", features = ["full"] } [build-dependencies] tokio = { version = "1", features = ["build-time"] }
The tokio runtime is set up and async I/O is ready to be used.
Reading Asynchronously
Rust's standard library provides async_std
or tokio
-specific types to handle asynchronous input. For example, in tokio
, use tokio::fs::File
:
use tokio::fs::File; use tokio::io::prelude::*; #[tokio::main] async fn main() { let mut file = File::open("example.txt") .await .expect("Failed to open file"); let mut contents = String::new(); file.read_to_string(&mut contents) .await .expect("Failed to read file"); println!("File contents: {}", contents); }
File contents: This is a sample text file for asynchronous I/O in Rust.
Writing Asynchronously
Writing data asynchronously also leverages the async APIs provided by the chosen runtime. In the example below, we'll write string data to a file using tokio
:
use tokio::fs::File; use tokio::io::prelude::*; #[tokio::main] async fn main() { let mut file = File::create("output.txt") .await .expect("Failed to create file"); let data = "Hello, asynchronous Rust