//! Traits, helpers, and type definitions for core I/O functionality. //! //! The `async_std::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. //! //! This module is an async version of [`std::io`]. //! //! [`std::io`]: https://doc.rust-lang.org/std/io/index.html //! //! # 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: [`File`]s, [`TcpStream`]s, and sometimes even [`Vec`]s. For //! example, [`Read`] adds a [`read`][`Read::read`] method, which we can use on //! [`File`]s: //! //! ```no_run //! use async_std::fs::File; //! use async_std::prelude::*; //! //! # fn main() -> std::io::Result<()> { async_std::task::block_on(async { //! # //! let mut f = File::open("foo.txt").await?; //! let mut buffer = [0; 10]; //! //! // read up to 10 bytes //! let n = f.read(&mut buffer).await?; //! //! 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: //! //! ```no_run //! use async_std::fs::File; //! use async_std::io::SeekFrom; //! use async_std::prelude::*; //! //! # fn main() -> std::io::Result<()> { async_std::task::block_on(async { //! # //! let mut f = File::open("foo.txt").await?; //! let mut buffer = [0; 10]; //! //! // skip to the last 10 bytes of the file //! f.seek(SeekFrom::End(-10)).await?; //! //! // read up to 10 bytes //! let n = f.read(&mut buffer).await?; //! //! 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: //! //! ```no_run //! use async_std::fs::File; //! use async_std::io::BufReader; //! use async_std::prelude::*; //! //! # fn main() -> std::io::Result<()> { async_std::task::block_on(async { //! # //! let f = File::open("foo.txt").await?; //! let mut reader = BufReader::new(f); //! let mut buffer = String::new(); //! //! // read a line into buffer //! reader.read_line(&mut buffer).await?; //! //! println!("{}", buffer); //! # //! # Ok(()) }) } //! ``` //! //! [`BufWriter`] doesn't add any new ways of writing; it just buffers every call //! to [`write`][`Write::write`]: //! //! ```no_run //! use async_std::fs::File; //! use async_std::io::prelude::*; //! use async_std::io::BufWriter; //! //! # fn main() -> std::io::Result<()> { async_std::task::block_on(async { //! # //! let f = File::create("foo.txt").await?; //! { //! let mut writer = BufWriter::new(f); //! //! // write a byte to the buffer //! writer.write(&[42]).await?; //! } // the buffer is flushed once writer goes out of scope //! // //! # //! # Ok(()) }) } //! ``` //! //! ## Standard input and output //! //! A very common source of input is standard input: //! //! ```no_run //! use async_std::io; //! //! # fn main() -> std::io::Result<()> { async_std::task::block_on(async { //! # //! let mut input = String::new(); //! //! io::stdin().read_line(&mut input).await?; //! //! println!("You typed: {}", input.trim()); //! # //! # Ok(()) }) } //! ``` //! //! Note that you cannot use the [`?` operator] in functions that do not return //! a [`Result`][`Result`]. Instead, you can call [`.unwrap()`] //! or `match` on the return value to catch any possible errors: //! //! ```no_run //! use async_std::io; //! //! # fn main() -> std::io::Result<()> { async_std::task::block_on(async { //! # //! let mut input = String::new(); //! //! io::stdin().read_line(&mut input).await.unwrap(); //! # //! # Ok(()) }) } //! ``` //! //! And a very common source of output is standard output: //! //! ```no_run //! use async_std::io; //! use async_std::io::prelude::*; //! //! # fn main() -> std::io::Result<()> { async_std::task::block_on(async { //! # //! io::stdout().write(&[42]).await?; //! # //! # Ok(()) }) } //! ``` //! //! Of course, using [`io::stdout`] directly is less common than something like //! [`println!`]. //! //! ## 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: //! //! ```no_run //! use async_std::fs::File; //! use async_std::io::BufReader; //! use async_std::prelude::*; //! //! # fn main() -> std::io::Result<()> { async_std::task::block_on(async { //! # //! let f = File::open("foo.txt").await?; //! let reader = BufReader::new(f); //! //! let mut lines = reader.lines(); //! while let Some(line) = lines.next().await { //! println!("{}", line?); //! } //! # //! # Ok(()) }) } //! ``` //! //! ## Functions //! //! There are a number of [functions][functions-list] that offer access to various //! features. For example, we can use three of these functions to copy everything //! from standard input to standard output: //! //! ```no_run //! use async_std::io; //! //! # fn main() -> std::io::Result<()> { async_std::task::block_on(async { //! # //! io::copy(&mut io::stdin(), &mut io::stdout()).await?; //! # //! # Ok(()) }) } //! ``` //! //! [functions-list]: #functions-1 //! //! ## 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]: //! //! ``` //! #![allow(dead_code)] //! use async_std::io; //! //! async fn read_input() -> io::Result<()> { //! let mut input = String::new(); //! //! io::stdin().read_line(&mut input).await?; //! //! println!("You typed: {}", input.trim()); //! //! Ok(()) //! } //! ``` //! //! The return type of `read_input`, [`io::Result<()>`][`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 `()`. //! //! ## Platform-specific behavior //! //! Many I/O functions throughout the standard library are documented to indicate //! what various library or syscalls they are delegated to. This is done to help //! applications both understand what's happening under the hood as well as investigate //! any possibly unclear semantics. Note, however, that this is informative, not a binding //! contract. The implementation of many of these functions are subject to change over //! time and may call fewer or more syscalls/library functions. //! //! [`Read`]: trait.Read.html //! [`Write`]: trait.Write.html //! [`Seek`]: trait.Seek.html //! [`BufRead`]: trait.BufRead.html //! [`File`]: ../fs/struct.File.html //! [`TcpStream`]: ../net/struct.TcpStream.html //! [`Vec`]: ../vec/struct.Vec.html //! [`BufReader`]: struct.BufReader.html //! [`BufWriter`]: struct.BufWriter.html //! [`Write::write`]: trait.Write.html#tymethod.write //! [`io::stdout`]: fn.stdout.html //! [`println!`]: ../macro.println.html //! [`Lines`]: struct.Lines.html //! [`io::Result`]: type.Result.html //! [`?` operator]: https://doc.rust-lang.org/stable/book/appendix-02-operators.html //! [`Read::read`]: trait.Read.html#tymethod.read //! [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html //! [`.unwrap()`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap const DEFAULT_BUF_SIZE: usize = 8 * 1024; cfg_std! { #[doc(inline)] pub use std::io::{Error, ErrorKind, IoSlice, IoSliceMut, Result, SeekFrom}; pub use buf_read::{BufRead, Lines, Split}; pub use buf_reader::BufReader; pub use buf_writer::{BufWriter, IntoInnerError}; pub use copy::copy; pub use cursor::Cursor; pub use empty::{empty, Empty}; pub use read::*; pub use repeat::{repeat, Repeat}; pub use seek::Seek; pub use sink::{sink, Sink}; pub use write::Write; pub mod prelude; pub(crate) mod buf_read; pub(crate) mod read; pub(crate) mod seek; pub(crate) mod write; pub(crate) mod utils; mod buf_reader; mod buf_writer; mod copy; mod cursor; mod empty; mod repeat; mod sink; } cfg_default! { // For use in the print macros. #[doc(hidden)] #[cfg(not(target_os = "unknown"))] pub use stdio::{_eprint, _print}; #[cfg(not(target_os = "unknown"))] pub use stderr::{stderr, Stderr}; #[cfg(not(target_os = "unknown"))] pub use stdin::{stdin, Stdin}; #[cfg(not(target_os = "unknown"))] pub use stdout::{stdout, Stdout}; pub use timeout::timeout; mod timeout; #[cfg(not(target_os = "unknown"))] mod stderr; #[cfg(not(target_os = "unknown"))] mod stdin; #[cfg(not(target_os = "unknown"))] mod stdio; #[cfg(not(target_os = "unknown"))] mod stdout; } cfg_unstable_default! { #[cfg(not(target_os = "unknown"))] pub use stderr::StderrLock; #[cfg(not(target_os = "unknown"))] pub use stdin::StdinLock; #[cfg(not(target_os = "unknown"))] pub use stdout::StdoutLock; }