Struct Stdout

pub struct Stdout { /* private fields */ }

A handle to the standard output stream of a process.

Concurrent writes to stdout must be executed with care: Only individual writes to this AsyncWrite are guaranteed to be intact. In particular you should be aware that writes using write_all are not guaranteed to occur as a single write, so multiple threads writing data with write_all may result in interleaved output.

Warning

Each call to [stdout()] creates a new handle with its own internal state. Writes through different handles are not coordinated, so creating a new handle in a loop can cause output to appear out of order:

# use tokio::io::{self, AsyncWriteExt};
# #[tokio::main]
# async fn main() -> std::io::Result<()> {
// WRONG: creates a new handle each iteration
for i in 0..10 {
    let mut out = io::stdout();
    out.write_all(b"data").await?;
    out.write_all(b"\n").await?;
    // out is dropped here; its last write may still be
    // running when the next iteration starts
}
# Ok(())
# }

To preserve order, create one handle outside the loop and reuse it:

# use tokio::io::{self, AsyncWriteExt};
# #[tokio::main]
# async fn main() -> std::io::Result<()> {
let mut out = io::stdout();
for i in 0..10 {
    out.write_all(b"data").await?;
    out.write_all(b"\n").await?;
}
# Ok(())
# }

Created by the stdout function.

Examples

use tokio::io::{self, AsyncWriteExt};

#[tokio::main]
async fn main() -> io::Result<()> {
    let mut stdout = io::stdout();
    stdout.write_all(b"Hello world!").await?;
    Ok(())
}

The following is an example of using stdio with loop.

use tokio::io::{self, AsyncWriteExt};

#[tokio::main]
async fn main() {
    let messages = vec!["hello", " world\n"];

    // When you use `stdio` in a loop, it is recommended to create
    // a single `stdio` instance outside the loop and call a write
    // operation against that instance on each loop.
    //
    // Repeatedly creating `stdout` instances inside the loop and
    // writing to that handle could result in mangled output since
    // each write operation is handled by a different blocking thread.
    let mut stdout = io::stdout();

    for message in &messages {
        stdout.write_all(message.as_bytes()).await.unwrap();
        stdout.flush().await.unwrap();
    }
}

Trait Implementations

impl AsFd for Stdout

fn as_fd(&self) -> BorrowedFd<'_>

impl AsRawFd for Stdout

fn as_raw_fd(&self) -> RawFd

impl AsyncWrite for Stdout

fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>>
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Error>>
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Error>>

impl Debug for Stdout

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Auto Trait Implementations

impl Freeze for Stdout

impl RefUnwindSafe for Stdout

impl Send for Stdout

impl Sync for Stdout

impl Unpin for Stdout

impl UnsafeUnpin for Stdout

impl UnwindSafe for Stdout

Blanket Implementations

impl<T> Any for Stdout where T: 'static + ?Sized,

fn type_id(&self) -> TypeId

impl<T> Borrow<T> for Stdout where T: ?Sized,

fn borrow(&self) -> &T

impl<T> BorrowMut<T> for Stdout where T: ?Sized,

fn borrow_mut(&mut self) -> &mut T

impl<T> From<T> for Stdout

fn from(t: T) -> T

Returns the argument unchanged.

impl<T, U> Into<U> for Stdout where U: From<T>,

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom<U> for Stdout where U: Into<T>,

type Error = never;
fn try_from(value: U) -> Result<T, never>

impl<T, U> TryInto<U> for Stdout where U: TryFrom<T>,

type Error = <U as TryFrom<T>>::Error;
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

impl<W> AsyncWriteExt for Stdout where W: AsyncWrite + ?Sized,