Skip to main content

Module io

Module io 

Source
🔬This is a nightly-only experimental API. (alloc_io #154046)
Expand description

Traits, helpers, and type definitions for core I/O functionality.

The io module contains a number of common things you’ll need when doing input and output. The most core part of this module is the Read and Write traits, which provide the most general interface for reading and writing input and output.

§Read and Write

Because they are traits, Read and Write are implemented by a number of other types, and you can implement them for your types too. As such, you’ll see a few different types of I/O throughout the documentation in this module: Files, TcpStreams, and sometimes even Vec<T>s. For example, Read adds a read method, which we can use on Files:

use std::io;
use std::io::prelude::*;
use std::fs::File;

fn main() -> io::Result<()> {
    let mut f = File::open("foo.txt")?;
    let mut buffer = [0; 10];

    // read up to 10 bytes
    let n = f.read(&mut buffer)?;

    println!("The bytes: {:?}", &buffer[..n]);
    Ok(())
}

Read and Write are so important, implementors of the two traits have a nickname: readers and writers. So you’ll sometimes see ‘a reader’ instead of ‘a type that implements the Read trait’. Much easier!

§Seek and BufRead

Beyond that, there are two important traits that are provided: Seek and BufRead. Both of these build on top of a reader to control how the reading happens. Seek lets you control where the next byte is coming from:

use std::io;
use std::io::prelude::*;
use std::io::SeekFrom;
use std::fs::File;

fn main() -> io::Result<()> {
    let mut f = File::open("foo.txt")?;
    let mut buffer = [0; 10];

    // skip to the last 10 bytes of the file
    f.seek(SeekFrom::End(-10))?;

    // read up to 10 bytes
    let n = f.read(&mut buffer)?;

    println!("The bytes: {:?}", &buffer[..n]);
    Ok(())
}

BufRead uses an internal buffer to provide a number of other ways to read, but to show it off, we’ll need to talk about buffers in general. Keep reading!

§BufReader and BufWriter

Byte-based interfaces are unwieldy and can be inefficient, as we’d need to be making near-constant calls to the operating system. To help with this, std::io comes with two structs, BufReader and BufWriter, which wrap readers and writers. The wrapper uses a buffer, reducing the number of calls and providing nicer methods for accessing exactly what you want.

For example, BufReader works with the BufRead trait to add extra methods to any reader:

use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;

fn main() -> io::Result<()> {
    let f = File::open("foo.txt")?;
    let mut reader = BufReader::new(f);
    let mut buffer = String::new();

    // read a line into buffer
    reader.read_line(&mut buffer)?;

    println!("{buffer}");
    Ok(())
}

BufWriter doesn’t add any new ways of writing; it just buffers every call to write:

use std::io;
use std::io::prelude::*;
use std::io::BufWriter;
use std::fs::File;

fn main() -> io::Result<()> {
    let f = File::create("foo.txt")?;
    {
        let mut writer = BufWriter::new(f);

        // write a byte to the buffer
        writer.write(&[42])?;

    } // the buffer is flushed once writer goes out of scope

    Ok(())
}

§Iterator types

A large number of the structures provided by std::io are for various ways of iterating over I/O. For example, Lines is used to split over lines:

use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;

fn main() -> io::Result<()> {
    let f = File::open("foo.txt")?;
    let reader = BufReader::new(f);

    for line in reader.lines() {
        println!("{}", line?);
    }
    Ok(())
}

§io::Result

Last, but certainly not least, is io::Result. This type is used as the return type of many std::io functions that can cause an error, and can be returned from your own functions as well. Many of the examples in this module use the ? operator:

use std::io;

fn read_input() -> io::Result<()> {
    let mut input = String::new();

    io::stdin().read_line(&mut input)?;

    println!("You typed: {}", input.trim());

    Ok(())
}

The return type of read_input(), io::Result<()>, is a very common type for functions which don’t have a ‘real’ return value, but do want to return errors if they happen. In this case, the only purpose of this function is to read the line and print it, so we use ().

Re-exports§

pub use core::io::IoHandle; 👻 Experimental
pub use core::io::OsFunctions; 👻 Experimental
pub use core::io::default_write_vectored; 👻 Experimental
pub use core::io::stream_len_default; 👻 Experimental
pub use self::buf_read::BufRead;
pub use self::buffered::BufReader;
pub use self::buffered::BufWriter;
pub use self::buffered::IntoInnerError;
pub use self::buffered::LineWriter;
pub use self::buffered::WriterPanicked;
pub use self::copy::copy;
pub use self::read::Read;
pub use self::read::read_to_string;
pub use self::util::Bytes;
pub use self::util::Lines;
pub use self::util::Split;
pub use self::copy::CopyState; 👻 Experimental
pub use self::copy::SpecCopy; 👻 Experimental
pub use self::read::DEFAULT_BUF_SIZE; 👻 Experimental
pub use self::read::default_read_buf; 👻 Experimental
pub use self::read::default_read_to_end; 👻 Experimental
pub use self::read::default_read_to_string; 👻 Experimental
pub use self::read::default_read_vectored; 👻 Experimental
pub use self::util::SpecReadByte; 👻 Experimental

Modules§

buf_read 🔒 Experimental
buffered 🔒 Experimental
Buffering wrappers for I/O traits
copy 🔒 Experimental
cursor 🔒 Experimental
error 🔒 Experimental
impls 🔒 Experimental
preludeExperimental
The I/O Prelude.
read 🔒 Experimental
util 🔒 Experimental

Macros§

const_errorExperimental
Creates a new I/O error from a known kind of error and a string literal.

Structs§

BorrowedBufExperimental
A borrowed buffer of initially uninitialized elements, which is incrementally filled.
BorrowedCursorExperimental
A writeable view of the unfilled portion of a BorrowedBuf.
ChainExperimental
Adapter to chain together two readers.
CursorExperimental
A Cursor wraps an in-memory buffer and provides it with a Seek implementation.
EmptyExperimental
Empty ignores any data written via Write, and will always be empty (returning zero bytes) when read via Read.
ErrorExperimental
The error type for I/O operations of the Read, Write, Seek, and associated traits.
IoSliceExperimental
A buffer type used with Write::write_vectored.
IoSliceMutExperimental
A buffer type used with Read::read_vectored.
RepeatExperimental
A reader which yields one byte over and over and over and over and over and…
SimpleMessage 👻 Experimental
SinkExperimental
A writer which will move data into the void.
TakeExperimental
Reader adapter which limits the bytes read from an underlying reader.

Enums§

ErrorKindExperimental
A list specifying general categories of I/O error.
SeekFromExperimental
Enumeration of possible methods to seek within an I/O object.

Traits§

SeekExperimental
The Seek trait provides a cursor which can be moved within a stream of bytes.
WriteExperimental
A trait for objects which are byte-oriented sinks.

Functions§

emptyExperimental
Creates a value that is always at EOF for reads, and ignores all data written.
repeatExperimental
Creates an instance of a reader that infinitely repeats one byte.
sinkExperimental
Creates an instance of a writer which will successfully consume all data.

Type Aliases§

RawOsErrorExperimental
The type of raw OS error codes.
ResultExperimental
A specialized Result type for I/O operations.