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/// # Examples
34///
35/// ```no_run
36/// use tokio::fs;
37/// use std::net::SocketAddr;
38///
39/// #[tokio::main]
40/// async fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {
41/// let contents = fs::read("address.txt").await?;
42/// let foo: SocketAddr = String::from_utf8_lossy(&contents).parse()?;
43/// Ok(())
44/// }
45/// ```
46pub async fn read(path: impl AsRef<Path>) -> io::Result<Vec<u8>> {
47 let path = path.as_ref().to_owned();
48 asyncify(move || std::fs::read(path)).await
49}
50