BufReader

Struct BufReader 

Source
pub struct BufReader<R> { /* private fields */ }
Expand description

Adds buffering to any reader, similar to the standard BufReader, but performs non-buffer reads in a thread pool.

All reads are returned as futures.

This reader is most useful for wrapping readers that never block or cannot return EWOULDBLOCK, but are slow. Notably, this is useful for wrapping io::File.

All reads must take and own the BufReader and the buffer being written for the duration of the read.

§Examples

let f = io::Cursor::new(b"normally, we would open a file here here".to_vec());
let pool = CpuPool::new(1);
let reader = BufReader::with_pool_and_capacity(pool, 10, f);

let buf = vec![0; 10];
let (reader, buf, n) = reader.try_read_full(buf).wait().unwrap_or_else(|(_, _, e)| {
    // in real usage, we have the option to deconstruct our BufReader or reuse buf here
    panic!("unable to read full: {}", e);
});
assert_eq!(n, 10);
assert_eq!(&buf[..n], b"normally, ");

Implementations§

Source§

impl<R: Read + Send + 'static> BufReader<R>

Source

pub fn with_pool_and_capacity( pool: CpuPool, cap: usize, inner: R, ) -> BufReader<R>

Creates and returns a new BufReader with an internal buffer of size cap.

§Examples
let f = io::Cursor::new(b"foo text".to_vec());
let pool = CpuPool::new(1);
let reader = BufReader::with_pool_and_capacity(pool, 4<<10, f);
Source

pub fn with_pool_and_buf( pool: CpuPool, buf: Box<[u8]>, inner: R, ) -> BufReader<R>

Creates and returns a new BufReader with buf as the internal buffer.

§Examples
let f = io::Cursor::new(b"foo text".to_vec());
let pool = CpuPool::new(1);
let buf = vec![0; 4096].into_boxed_slice();
let reader = BufReader::with_pool_and_buf(pool, buf, f);
Source

pub fn get_ref(&self) -> &R

Gets a reference to the underlying reader.

It is likely invalid to read directly from the underlying reader and then use the BufReader again.

Source

pub fn get_mut(&mut self) -> &R

Gets a mutable reference to the underlying reader.

It is likely invalid to read directly from the underlying reader and then use the BufReader again.

Source

pub unsafe fn set_pos(&mut self, pos: usize)

Sets the BufReaders internal buffer position to pos.

This is highly unsafe for the following reasons:

  • the internal buffer may have uninitialized memory, and moving the read position back will mean reading uninitialized memory

  • the pos is not validated, meaning it is possible to move the pos past the end of the internal buffer. This will cause a panic on the next use of try_read_full.

  • it is possible to move past the internal “capacity” end position, meaning a read may panic due to the beginning of a read being after its end.

This function should only be used for setting up a new BufReader with a buffer that contains known, existing contents.

§Examples
let f = io::Cursor::new(vec![]);
let pool = CpuPool::new(1);
let mut buf = vec![0; 4096].into_boxed_slice();

let p = b"pre-existing text";
let buf_len = buf.len();

// copy some known text to our buffer - note it must be at the end
&mut buf[buf_len-p.len()..].copy_from_slice(p);

let mut reader = BufReader::with_pool_and_buf(pool, buf, f);

// unsafely move the reader's position to the beginning of our known text, and read it
unsafe { reader.set_pos(buf_len-p.len()); }
let (_, b, _) = reader
    .try_read_full(vec![0; p.len()])
    .wait()
    .unwrap_or_else(|(_, _, e)| {
        panic!("unable to read: {}", e);
    });

// our read should be all of our known contents
assert_eq!(&*b, p);
Source

pub unsafe fn components(self) -> (R, Box<[u8]>, CpuPool)

Returns the internal components of a BufReader, allowing reuse. This is unsafe because it does not zero the memory of the buffer, meaning the buffer could countain uninitialized memory.

§Examples
let f = io::Cursor::new(b"foo text".to_vec());
let pool = CpuPool::new(1);
let reader = BufReader::with_pool_and_capacity(pool, 4<<10, f);

let (f, buf, pool) = unsafe { reader.components() };
assert_eq!(f.get_ref(), b"foo text");
assert_eq!(buf.len(), 4<<10);
Source

pub fn try_read_full<B>( self, buf: B, ) -> impl Future<Item = (Self, B, usize), Error = (Self, B, Error)>
where B: DerefMut<Target = [u8]> + Send + 'static,

Reads into buf until buf is filled or the underlying reader returns a zero read (hits EOF).

This returns the buffer and the number of bytes read. The buffer may need sized down on use if this returns with a short read.

If used on io::File’s, BufReader could be valuable for performing page-aligned reads. In this case, once this function returns a short read, we reached EOF and any futures reads may be un-aligned.

§Examples
let f = io::Cursor::new(b"foo text".to_vec());
let pool = CpuPool::new(1);
let reader = BufReader::with_pool_and_capacity(pool, 10, f);

let buf = vec![0; 10];
let (reader, buf, n) = reader.try_read_full(buf).wait().unwrap_or_else(|(_, _, e)| {
    // in real usage, we have the option to deconstruct our BufReader or reuse buf here
    panic!("unable to read full: {}", e);
});
assert_eq!(n, 8);
assert_eq!(&*buf, b"foo text\0\0");
assert_eq!(&buf[..n], b"foo text");

Auto Trait Implementations§

§

impl<R> Freeze for BufReader<R>
where R: Freeze,

§

impl<R> RefUnwindSafe for BufReader<R>
where R: RefUnwindSafe,

§

impl<R> Send for BufReader<R>
where R: Send,

§

impl<R> Sync for BufReader<R>
where R: Sync,

§

impl<R> Unpin for BufReader<R>
where R: Unpin,

§

impl<R> UnwindSafe for BufReader<R>
where R: UnwindSafe,

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

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

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

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

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

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

Performs the conversion.