Coverage Report

Created: 2026-03-20 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.50.0/src/fs/write.rs
Line
Count
Source
1
use crate::{fs::asyncify, util::as_ref::OwnedBuf};
2
3
use std::{io, path::Path};
4
5
/// Creates a future that will open a file for writing and write the entire
6
/// contents of `contents` to it.
7
///
8
/// This is the async equivalent of [`std::fs::write`][std].
9
///
10
/// This operation is implemented by running the equivalent blocking operation
11
/// on a separate thread pool using [`spawn_blocking`].
12
///
13
/// [`spawn_blocking`]: crate::task::spawn_blocking
14
/// [std]: fn@std::fs::write
15
///
16
/// # Examples
17
///
18
/// ```no_run
19
/// use tokio::fs;
20
///
21
/// # async fn dox() -> std::io::Result<()> {
22
/// fs::write("foo.txt", b"Hello world!").await?;
23
/// # Ok(())
24
/// # }
25
/// ```
26
0
pub async fn write(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> io::Result<()> {
27
0
    let path = path.as_ref();
28
0
    let contents = crate::util::as_ref::upgrade(contents);
29
30
    #[cfg(all(
31
        tokio_unstable,
32
        feature = "io-uring",
33
        feature = "rt",
34
        feature = "fs",
35
        target_os = "linux"
36
    ))]
37
    {
38
        let handle = crate::runtime::Handle::current();
39
        let driver_handle = handle.inner.driver().io();
40
        if driver_handle
41
            .check_and_init(io_uring::opcode::Write::CODE)
42
            .await?
43
        {
44
            return write_uring(path, contents).await;
45
        }
46
    }
47
48
0
    write_spawn_blocking(path, contents).await
49
0
}
50
51
#[cfg(all(
52
    tokio_unstable,
53
    feature = "io-uring",
54
    feature = "rt",
55
    feature = "fs",
56
    target_os = "linux"
57
))]
58
async fn write_uring(path: &Path, mut buf: OwnedBuf) -> io::Result<()> {
59
    use crate::{fs::OpenOptions, runtime::driver::op::Op};
60
    use std::os::fd::OwnedFd;
61
62
    let file = OpenOptions::new()
63
        .write(true)
64
        .create(true)
65
        .truncate(true)
66
        .open(path)
67
        .await?;
68
69
    let mut fd: OwnedFd = file
70
        .try_into_std()
71
        .expect("unexpected in-flight operation detected")
72
        .into();
73
74
    let total: usize = buf.as_ref().len();
75
    let mut buf_offset: usize = 0;
76
    let mut file_offset: u64 = 0;
77
    while buf_offset < total {
78
        let (res, _buf, _fd) = Op::write_at(fd, buf, buf_offset, file_offset)?.await;
79
80
        let n = match res {
81
            Ok(0) => return Err(io::ErrorKind::WriteZero.into()),
82
            Ok(n) => n,
83
            Err(e) if e.kind() == io::ErrorKind::Interrupted => 0,
84
            Err(e) => return Err(e),
85
        };
86
87
        buf = _buf;
88
        fd = _fd;
89
        buf_offset += n as usize;
90
        file_offset += n as u64;
91
    }
92
93
    Ok(())
94
}
95
96
0
async fn write_spawn_blocking(path: &Path, contents: OwnedBuf) -> io::Result<()> {
97
0
    let path = path.to_owned();
98
0
    asyncify(move || std::fs::write(path, contents)).await
99
0
}