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>
impl<R: Read + Send + 'static> BufReader<R>
Sourcepub fn with_pool_and_capacity(
pool: CpuPool,
cap: usize,
inner: R,
) -> BufReader<R>
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);Sourcepub fn with_pool_and_buf(
pool: CpuPool,
buf: Box<[u8]>,
inner: R,
) -> BufReader<R>
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);Sourcepub fn get_ref(&self) -> &R
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.
Sourcepub fn get_mut(&mut self) -> &R
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.
Sourcepub unsafe fn set_pos(&mut self, pos: usize)
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);Sourcepub unsafe fn components(self) -> (R, Box<[u8]>, CpuPool)
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);Sourcepub fn try_read_full<B>(
self,
buf: B,
) -> impl Future<Item = (Self, B, usize), Error = (Self, B, Error)>
pub fn try_read_full<B>( self, buf: B, ) -> impl Future<Item = (Self, B, usize), Error = (Self, B, Error)>
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");