Struct io_streams::BufDuplexer[][src]

pub struct BufDuplexer<Inner: HalfDuplex> { /* fields omitted */ }
Expand description

Wraps a reader and writer and buffers their output.

It can be excessively inefficient to work directly with something that implements Write. For example, every call to write on TcpStream results in a system call. A BufDuplexer<Inner> keeps an in-memory buffer of data and writes it to an underlying writer in large, infrequent batches.

It can be excessively inefficient to work directly with a Read instance. For example, every call to read on TcpStream results in a system call. A BufDuplexer<Inner> performs large, infrequent reads on the underlying Read and maintains an in-memory buffer of the results.

BufDuplexer<Inner> can improve the speed of programs that make small and repeated write calls to the same file or network socket. It does not help when writing very large amounts at once, or writing just one or a few times. It also provides no advantage when writing to a destination that is in memory, like a Vec<u8>.

BufDuplexer<Inner> can improve the speed of programs that make small and repeated read calls to the same file or network socket. It does not help when reading very large amounts at once, or reading just one or a few times. It also provides no advantage when reading from a source that is already in memory, like a Vec<u8>.

It is critical to call flush before BufDuplexer<Inner> is dropped. Though dropping will attempt to flush the contents of the writer buffer, any errors that happen in the process of dropping will be ignored. Calling flush ensures that the writer buffer is empty and thus dropping will not even attempt file operations.

When the BufDuplexer<Inner> is dropped, the contents of its reader buffer will be discarded. Creating multiple instances of a BufDuplexer<Inner> on the same stream can cause data loss. Reading from the underlying reader after unwrapping the BufDuplexer<Inner> with BufDuplexer::into_inner can also cause data loss.

Examples

Let’s write the numbers one through ten to a TcpStream:

use std::{io::prelude::*, net::TcpStream};

let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();

for i in 0..10 {
    stream.write(&[i + 1]).unwrap();
}

Because we’re not buffering, we write each one in turn, incurring the overhead of a system call per byte written. We can fix this with a BufDuplexer<Inner>:

use io_streams::BufDuplexer;
use std::{io::prelude::*, net::TcpStream};

let mut stream = BufDuplexer::new(TcpStream::connect("127.0.0.1:34254").unwrap());

for i in 0..10 {
    stream.write(&[i + 1]).unwrap();
}
stream.flush().unwrap();

By wrapping the stream with a BufDuplexer<Inner>, these ten writes are all grouped together by the buffer and will all be written out in one system call when the stream is flushed.

use io_streams::BufDuplexer;
use std::{io::prelude::*, net::TcpStream};

fn main() -> std::io::Result<()> {
    let mut stream = BufDuplexer::new(TcpStream::connect("127.0.0.1:34254").unwrap());

    let mut line = String::new();
    let len = stream.read_line(&mut line)?;
    println!("First line is {} bytes long", len);
    Ok(())
}

Implementations

Creates a new BufDuplexer<Inner> with default buffer capacities. The default is currently 8 KB, but may change in the future.

Examples

use io_streams::BufDuplexer;
use std::net::TcpStream;

let mut buffer = BufDuplexer::new(TcpStream::connect("127.0.0.1:34254").unwrap());

Creates a new BufDuplexer<Inner> with the specified buffer capacities.

Examples

Creating a buffer with ten bytes of reader capacity and a writer buffer of a hundered bytes:

use io_streams::BufDuplexer;
use std::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:34254").unwrap();
let mut buffer = BufDuplexer::with_capacities(10, 100, stream);

Gets a reference to the underlying reader/writer.

Examples

use io_streams::BufDuplexer;
use std::net::TcpStream;

let mut buffer = BufDuplexer::new(TcpStream::connect("127.0.0.1:34254").unwrap());

// we can use reference just like buffer
let reference = buffer.get_ref();

Gets a mutable reference to the underlying reader/writer.

It is inadvisable to directly write to the underlying reader/writer.

Examples

use io_streams::BufDuplexer;
use std::net::TcpStream;

let mut buffer = BufDuplexer::new(TcpStream::connect("127.0.0.1:34254").unwrap());

// we can use reference just like buffer
let reference = buffer.get_mut();

Returns a reference to the internally buffered writer data.

Examples

use io_streams::BufDuplexer;
use std::net::TcpStream;

let buf_writer = BufDuplexer::new(TcpStream::connect("127.0.0.1:34254").unwrap());

// See how many bytes are currently buffered
let bytes_buffered = buf_writer.writer_buffer().len();

Returns a reference to the internally buffered reader data.

Unlike fill_buf, this will not attempt to fill the buffer if it is empty.

Examples

use char_device::CharDevice;
use io_streams::BufDuplexer;
use std::{fs::File, io::BufRead};

fn main() -> std::io::Result<()> {
    let f = CharDevice::new(File::open("/dev/ttyS0")?)?;
    let mut reader = BufDuplexer::new(f);
    assert!(reader.reader_buffer().is_empty());

    if reader.fill_buf()?.len() > 0 {
        assert!(!reader.reader_buffer().is_empty());
    }
    Ok(())
}

Returns the number of bytes the internal writer buffer can hold without flushing.

Examples

use io_streams::BufDuplexer;
use std::net::TcpStream;

let buf_duplexer = BufDuplexer::new(TcpStream::connect("127.0.0.1:34254").unwrap());

// Check the capacity of the inner buffer
let capacity = buf_duplexer.writer_capacity();
// Calculate how many bytes can be written without flushing
let without_flush = capacity - buf_duplexer.writer_buffer().len();

Returns the number of bytes the internal reader buffer can hold at once.

Examples

use char_device::CharDevice;
use io_streams::BufDuplexer;
use std::{fs::File, io::BufRead};

fn main() -> std::io::Result<()> {
    let f = CharDevice::new(File::open("/dev/tty")?)?;
    let mut reader = BufDuplexer::new(f);

    let capacity = reader.reader_capacity();
    let buffer = reader.fill_buf()?;
    assert!(buffer.len() <= capacity);
    Ok(())
}

Unwraps this BufDuplexer<Inner>, returning the underlying reader/writer.

The buffer is written out before returning the reader/writer.

Errors

An Err will be returned if an error occurs while flushing the buffer.

Examples

use io_streams::BufDuplexer;
use std::net::TcpStream;

let mut buffer = BufDuplexer::new(TcpStream::connect("127.0.0.1:34254").unwrap());

// unwrap the TcpStream and flush the buffer
let stream = buffer.into_inner().unwrap();

Trait Implementations

Extracts the raw file descriptor. Read more

Returns the contents of the internal buffer, filling it with more data from the inner reader if it is empty. Read more

Tells this buffer that amt bytes have been consumed from the buffer, so they should no longer be returned in calls to read. Read more

Read all bytes into buf until the delimiter byte or EOF is reached. Read more

Read all bytes until a newline (the 0xA byte) is reached, and append them to the provided buffer. Read more

Returns an iterator over the contents of this reader split on the byte byte. Read more

Returns an iterator over the lines of this reader. Read more

Formats the value using the given formatter. Read more

Pull some bytes from this source into the specified buffer, returning how many bytes were read. Read more

Like read, except that it reads into a slice of buffers. Read more

🔬 This is a nightly-only experimental API. (can_vector)

Determines if this Reader has an efficient read_vectored implementation. Read more

🔬 This is a nightly-only experimental API. (read_initializer)

Determines if this Reader can work with buffers of uninitialized memory. Read more

Read all bytes until EOF in this source, placing them into buf. Read more

Read all bytes until EOF in this source, appending them to buf. Read more

Read the exact number of bytes required to fill buf. Read more

Creates a “by reference” adaptor for this instance of Read. Read more

Transforms this Read instance to an Iterator over its bytes. Read more

Creates an adaptor which will chain this stream with another. Read more

Creates an adaptor which will read at most limit bytes from it. Read more

Write a buffer into this writer, returning how many bytes were written. Read more

Attempts to write an entire buffer into this writer. Read more

Like write, except that it writes from a slice of buffers. Read more

🔬 This is a nightly-only experimental API. (can_vector)

Determines if this Writer has an efficient write_vectored implementation. Read more

Flush this output stream, ensuring that all intermediately buffered contents reach their destination. Read more

🔬 This is a nightly-only experimental API. (write_all_vectored)

Attempts to write multiple buffers into this writer. Read more

Writes a formatted string into this writer, returning any error encountered. Read more

Creates a “by reference” adaptor for this instance of Write. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Return the contained unsafe file.

Utility for returning a value which dereferences to a &File or &mut File. Read more

Like as_file_view, but returns a value which is not explicitly tied to the lifetime of self. Read more

Utility for returning a value which dereferences to a &PipeReader or &mut PipeReader. Read more

Like as_pipe_reader_view, but returns a value which is not explicitly tied to the lifetime of self. Read more

Utility for returning a value which dereferences to a &PipeWriter or &mut PipeWriter. Read more

Like as_pipe_writer_view, but returns a value which is not explicitly tied to the lifetime of self. Read more

Test whether self.as_unsafe_file().as_unsafe_handle() is equal to other.as_unsafe_file().as_unsafe_handle(). Read more

Return the contained unsafe handle.

Test whether self.as_unsafe_handle() is equal to other.as_unsafe_handle(). Read more

Return the contained unsafe socket.

Utility for returning a value which dereferences to a &TcpStream or &mut TcpStream. Read more

Like as_tcp_stream_view, but returns a value which is not explicitly tied to the lifetime of self. Read more

Utility for returning a value which dereferences to a &TcpListener or &mut TcpListener. Read more

Like as_tcp_listener_view, but returns a value which is not explicitly tied to the lifetime of self. Read more

Utility for returning a value which dereferences to a &UdpSocket or &mut UdpSocket. Read more

Like as_udp_socket_view, but returns a value which is not explicitly tied to the lifetime of self. Read more

Utility for returning a value which dereferences to a &UnixStream or &mut UnixStream. Read more

Like as_unix_stream_view, but returns a value which is not explicitly tied to the lifetime of self. Read more

Test whether self.as_unsafe_socket().as_unsafe_handle() is equal to other.as_unsafe_socket().as_unsafe_handle(). Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Announce the expected access pattern of the data at the given offset.

Allocate space in the file, increasing the file size as needed, and ensuring that there are no holes under the given range. Read more

Pull some bytes from this source into the specified buffer, returning how many bytes were read. Read more

Read the exact number of bytes required to fill buf. Read more

Reads a number of bytes starting from a given offset. Read more

Reads the exact number of byte required to fill buf from the given offset. Read more

Like read, except that it reads into a slice of buffers. Read more

Is to read_vectored what read_at is to read.

Determines if this Reader has an efficient read_vectored_at implementation.

Read all bytes until EOF in this source, placing them into buf. Read more

Read all bytes, starting at offset, until EOF in this source, placing them into buf. Read more

Read all bytes until EOF in this source, appending them to buf. Read more

Read all bytes, starting at offset, until EOF in this source, appending them to buf. Read more

Read bytes from the current position without advancing the current position. Read more

Write a buffer into this writer, returning how many bytes were written. Read more

Attempts to write an entire buffer into this writer. Read more

Writes a number of bytes starting from a given offset. Read more

Attempts to write an entire buffer starting from a given offset. Read more

Like write, except that it writes from a slice of buffers. Read more

Is to write_vectored what write_at is to write.

Determines if this Writer has an efficient write_vectored_at implementation.

Flush this output stream, ensuring that all intermediately buffered contents reach their destination. Read more

Writes a formatted string into this writer, returning any error encountered. Read more

Seek to an offset, in bytes, in a stream. Read more

Returns the current seek position from the start of the stream. Read more

Is to read_vectored what read_exact is to read.

Is to read_exact_vectored what read_exact_at is to read_exact.

Is to write_vectored what write_all is to write.

Is to write_all_vectored what write_all_at is to write_all.

Performs the conversion.

Query the “status” flags for the self file descriptor.

Set the “status” flags for the self file descriptor. On some platforms, this may close the file descriptor and produce a new one. Read more

Performs the conversion.

Test whether the handle is readable and/or writable.

Test whether this output stream is attached to a terminal. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.