tokio/fs/
read.rs

1use crate::fs::asyncify;
2
3use std::{io, path::Path};
4
5/// Reads the entire contents of a file into a bytes vector.
6///
7/// This is an async version of [`std::fs::read`].
8///
9/// This is a convenience function for using [`File::open`] and [`read_to_end`]
10/// with fewer imports and without an intermediate variable. It pre-allocates a
11/// buffer based on the file size when available, so it is generally faster than
12/// reading into a vector created with `Vec::new()`.
13///
14/// This operation is implemented by running the equivalent blocking operation
15/// on a separate thread pool using [`spawn_blocking`].
16///
17/// [`File::open`]: super::File::open
18/// [`read_to_end`]: crate::io::AsyncReadExt::read_to_end
19/// [`spawn_blocking`]: crate::task::spawn_blocking
20///
21/// # Errors
22///
23/// This function will return an error if `path` does not already exist.
24/// Other errors may also be returned according to [`OpenOptions::open`].
25///
26/// [`OpenOptions::open`]: super::OpenOptions::open
27///
28/// It will also return an error if it encounters while reading an error
29/// of a kind other than [`ErrorKind::Interrupted`].
30///
31/// [`ErrorKind::Interrupted`]: std::io::ErrorKind::Interrupted
32///
33/// # io_uring support
34///
35/// On Linux, you can also use io_uring for executing system calls. To enable
36/// io_uring, you need to specify the `--cfg tokio_unstable` flag at compile time,
37/// enable the io-uring cargo feature, and set the `Builder::enable_io_uring`
38/// runtime option.
39///
40/// Support for io_uring is currently experimental, so its behavior may change
41/// or it may be removed in future versions.
42///
43/// # Examples
44///
45/// ```no_run
46/// use tokio::fs;
47/// use std::net::SocketAddr;
48///
49/// #[tokio::main]
50/// async fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {
51///     let contents = fs::read("address.txt").await?;
52///     let foo: SocketAddr = String::from_utf8_lossy(&contents).parse()?;
53///     Ok(())
54/// }
55/// ```
56pub async fn read(path: impl AsRef<Path>) -> io::Result<Vec<u8>> {
57    let path = path.as_ref().to_owned();
58
59    #[cfg(all(
60        tokio_unstable,
61        feature = "io-uring",
62        feature = "rt",
63        feature = "fs",
64        target_os = "linux"
65    ))]
66    {
67        use crate::fs::read_uring;
68
69        let handle = crate::runtime::Handle::current();
70        let driver_handle = handle.inner.driver().io();
71        if driver_handle.check_and_init()? {
72            return read_uring(&path).await;
73        }
74    }
75
76    asyncify(move || std::fs::read(path)).await
77}