3 use crate::io::{self, BufRead, Initializer, IoSliceMut, Read, Seek, SeekFrom, DEFAULT_BUF_SIZE};
5 /// The `BufReader<R>` struct adds buffering to any reader.
7 /// It can be excessively inefficient to work directly with a [`Read`] instance.
8 /// For example, every call to [`read`][`TcpStream::read`] on [`TcpStream`]
9 /// results in a system call. A `BufReader<R>` performs large, infrequent reads on
10 /// the underlying [`Read`] and maintains an in-memory buffer of the results.
12 /// `BufReader<R>` can improve the speed of programs that make *small* and
13 /// *repeated* read calls to the same file or network socket. It does not
14 /// help when reading very large amounts at once, or reading just one or a few
15 /// times. It also provides no advantage when reading from a source that is
16 /// already in memory, like a [`Vec`]`<u8>`.
18 /// When the `BufReader<R>` is dropped, the contents of its buffer will be
19 /// discarded. Creating multiple instances of a `BufReader<R>` on the same
20 /// stream can cause data loss. Reading from the underlying reader after
21 /// unwrapping the `BufReader<R>` with [`BufReader::into_inner`] can also cause
24 /// [`TcpStream::read`]: super::super::super::net::TcpStream::read
25 /// [`TcpStream`]: crate::net::TcpStream
30 /// use std::io::prelude::*;
31 /// use std::io::BufReader;
32 /// use std::fs::File;
34 /// fn main() -> std::io::Result<()> {
35 /// let f = File::open("log.txt")?;
36 /// let mut reader = BufReader::new(f);
38 /// let mut line = String::new();
39 /// let len = reader.read_line(&mut line)?;
40 /// println!("First line is {} bytes long", len);
44 #[stable(feature = "rust1", since = "1.0.0")]
45 pub struct BufReader<R> {
52 impl<R: Read> BufReader<R> {
53 /// Creates a new `BufReader<R>` with a default buffer capacity. The default is currently 8 KB,
54 /// but may change in the future.
59 /// use std::io::BufReader;
60 /// use std::fs::File;
62 /// fn main() -> std::io::Result<()> {
63 /// let f = File::open("log.txt")?;
64 /// let reader = BufReader::new(f);
68 #[stable(feature = "rust1", since = "1.0.0")]
69 pub fn new(inner: R) -> BufReader<R> {
70 BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
73 /// Creates a new `BufReader<R>` with the specified buffer capacity.
77 /// Creating a buffer with ten bytes of capacity:
80 /// use std::io::BufReader;
81 /// use std::fs::File;
83 /// fn main() -> std::io::Result<()> {
84 /// let f = File::open("log.txt")?;
85 /// let reader = BufReader::with_capacity(10, f);
89 #[stable(feature = "rust1", since = "1.0.0")]
90 pub fn with_capacity(capacity: usize, inner: R) -> BufReader<R> {
92 let mut buffer = Vec::with_capacity(capacity);
93 buffer.set_len(capacity);
94 inner.initializer().initialize(&mut buffer);
95 BufReader { inner, buf: buffer.into_boxed_slice(), pos: 0, cap: 0 }
100 impl<R> BufReader<R> {
101 /// Gets a reference to the underlying reader.
103 /// It is inadvisable to directly read from the underlying reader.
108 /// use std::io::BufReader;
109 /// use std::fs::File;
111 /// fn main() -> std::io::Result<()> {
112 /// let f1 = File::open("log.txt")?;
113 /// let reader = BufReader::new(f1);
115 /// let f2 = reader.get_ref();
119 #[stable(feature = "rust1", since = "1.0.0")]
120 pub fn get_ref(&self) -> &R {
124 /// Gets a mutable reference to the underlying reader.
126 /// It is inadvisable to directly read from the underlying reader.
131 /// use std::io::BufReader;
132 /// use std::fs::File;
134 /// fn main() -> std::io::Result<()> {
135 /// let f1 = File::open("log.txt")?;
136 /// let mut reader = BufReader::new(f1);
138 /// let f2 = reader.get_mut();
142 #[stable(feature = "rust1", since = "1.0.0")]
143 pub fn get_mut(&mut self) -> &mut R {
147 /// Returns a reference to the internally buffered data.
149 /// Unlike [`fill_buf`], this will not attempt to fill the buffer if it is empty.
151 /// [`fill_buf`]: BufRead::fill_buf
156 /// use std::io::{BufReader, BufRead};
157 /// use std::fs::File;
159 /// fn main() -> std::io::Result<()> {
160 /// let f = File::open("log.txt")?;
161 /// let mut reader = BufReader::new(f);
162 /// assert!(reader.buffer().is_empty());
164 /// if reader.fill_buf()?.len() > 0 {
165 /// assert!(!reader.buffer().is_empty());
170 #[stable(feature = "bufreader_buffer", since = "1.37.0")]
171 pub fn buffer(&self) -> &[u8] {
172 &self.buf[self.pos..self.cap]
175 /// Returns the number of bytes the internal buffer can hold at once.
180 /// use std::io::{BufReader, BufRead};
181 /// use std::fs::File;
183 /// fn main() -> std::io::Result<()> {
184 /// let f = File::open("log.txt")?;
185 /// let mut reader = BufReader::new(f);
187 /// let capacity = reader.capacity();
188 /// let buffer = reader.fill_buf()?;
189 /// assert!(buffer.len() <= capacity);
193 #[stable(feature = "buffered_io_capacity", since = "1.46.0")]
194 pub fn capacity(&self) -> usize {
198 /// Unwraps this `BufReader<R>`, returning the underlying reader.
200 /// Note that any leftover data in the internal buffer is lost. Therefore,
201 /// a following read from the underlying reader may lead to data loss.
206 /// use std::io::BufReader;
207 /// use std::fs::File;
209 /// fn main() -> std::io::Result<()> {
210 /// let f1 = File::open("log.txt")?;
211 /// let reader = BufReader::new(f1);
213 /// let f2 = reader.into_inner();
217 #[stable(feature = "rust1", since = "1.0.0")]
218 pub fn into_inner(self) -> R {
222 /// Invalidates all data in the internal buffer.
224 fn discard_buffer(&mut self) {
230 impl<R: Seek> BufReader<R> {
231 /// Seeks relative to the current position. If the new position lies within the buffer,
232 /// the buffer will not be flushed, allowing for more efficient seeks.
233 /// This method does not return the location of the underlying reader, so the caller
234 /// must track this information themselves if it is required.
235 #[unstable(feature = "bufreader_seek_relative", issue = "31100")]
236 pub fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
237 let pos = self.pos as u64;
239 if let Some(new_pos) = pos.checked_sub((-offset) as u64) {
240 self.pos = new_pos as usize;
244 if let Some(new_pos) = pos.checked_add(offset as u64) {
245 if new_pos <= self.cap as u64 {
246 self.pos = new_pos as usize;
251 self.seek(SeekFrom::Current(offset)).map(drop)
255 #[stable(feature = "rust1", since = "1.0.0")]
256 impl<R: Read> Read for BufReader<R> {
257 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
258 // If we don't have any buffered data and we're doing a massive read
259 // (larger than our internal buffer), bypass our internal buffer
261 if self.pos == self.cap && buf.len() >= self.buf.len() {
262 self.discard_buffer();
263 return self.inner.read(buf);
266 let mut rem = self.fill_buf()?;
273 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
274 let total_len = bufs.iter().map(|b| b.len()).sum::<usize>();
275 if self.pos == self.cap && total_len >= self.buf.len() {
276 self.discard_buffer();
277 return self.inner.read_vectored(bufs);
280 let mut rem = self.fill_buf()?;
281 rem.read_vectored(bufs)?
287 fn is_read_vectored(&self) -> bool {
288 self.inner.is_read_vectored()
291 // we can't skip unconditionally because of the large buffer case in read.
292 unsafe fn initializer(&self) -> Initializer {
293 self.inner.initializer()
297 #[stable(feature = "rust1", since = "1.0.0")]
298 impl<R: Read> BufRead for BufReader<R> {
299 fn fill_buf(&mut self) -> io::Result<&[u8]> {
300 // If we've reached the end of our internal buffer then we need to fetch
301 // some more data from the underlying reader.
302 // Branch using `>=` instead of the more correct `==`
303 // to tell the compiler that the pos..cap slice is always valid.
304 if self.pos >= self.cap {
305 debug_assert!(self.pos == self.cap);
306 self.cap = self.inner.read(&mut self.buf)?;
309 Ok(&self.buf[self.pos..self.cap])
312 fn consume(&mut self, amt: usize) {
313 self.pos = cmp::min(self.pos + amt, self.cap);
317 #[stable(feature = "rust1", since = "1.0.0")]
318 impl<R> fmt::Debug for BufReader<R>
322 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
323 fmt.debug_struct("BufReader")
324 .field("reader", &self.inner)
325 .field("buffer", &format_args!("{}/{}", self.cap - self.pos, self.buf.len()))
330 #[stable(feature = "rust1", since = "1.0.0")]
331 impl<R: Seek> Seek for BufReader<R> {
332 /// Seek to an offset, in bytes, in the underlying reader.
334 /// The position used for seeking with [`SeekFrom::Current`]`(_)` is the
335 /// position the underlying reader would be at if the `BufReader<R>` had no
338 /// Seeking always discards the internal buffer, even if the seek position
339 /// would otherwise fall within it. This guarantees that calling
340 /// [`BufReader::into_inner()`] immediately after a seek yields the underlying reader
341 /// at the same position.
343 /// To seek without discarding the internal buffer, use [`BufReader::seek_relative`].
345 /// See [`std::io::Seek`] for more details.
347 /// Note: In the edge case where you're seeking with [`SeekFrom::Current`]`(n)`
348 /// where `n` minus the internal buffer length overflows an `i64`, two
349 /// seeks will be performed instead of one. If the second seek returns
350 /// [`Err`], the underlying reader will be left at the same position it would
351 /// have if you called `seek` with [`SeekFrom::Current`]`(0)`.
353 /// [`std::io::Seek`]: Seek
354 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
356 if let SeekFrom::Current(n) = pos {
357 let remainder = (self.cap - self.pos) as i64;
358 // it should be safe to assume that remainder fits within an i64 as the alternative
359 // means we managed to allocate 8 exbibytes and that's absurd.
360 // But it's not out of the realm of possibility for some weird underlying reader to
361 // support seeking by i64::MIN so we need to handle underflow when subtracting
363 if let Some(offset) = n.checked_sub(remainder) {
364 result = self.inner.seek(SeekFrom::Current(offset))?;
366 // seek backwards by our remainder, and then by the offset
367 self.inner.seek(SeekFrom::Current(-remainder))?;
368 self.discard_buffer();
369 result = self.inner.seek(SeekFrom::Current(n))?;
372 // Seeking with Start/End doesn't care about our buffer length.
373 result = self.inner.seek(pos)?;
375 self.discard_buffer();
379 /// Returns the current seek position from the start of the stream.
381 /// The value returned is equivalent to `self.seek(SeekFrom::Current(0))`
382 /// but does not flush the internal buffer. Due to this optimization the
383 /// function does not guarantee that calling `.into_inner()` immediately
384 /// afterwards will yield the underlying reader at the same position. Use
385 /// [`BufReader::seek`] instead if you require that guarantee.
389 /// This function will panic if the position of the inner reader is smaller
390 /// than the amount of buffered data. That can happen if the inner reader
391 /// has an incorrect implementation of [`Seek::stream_position`], or if the
392 /// position has gone out of sync due to calling [`Seek::seek`] directly on
393 /// the underlying reader.
398 /// #![feature(seek_convenience)]
400 /// io::{self, BufRead, BufReader, Seek},
404 /// fn main() -> io::Result<()> {
405 /// let mut f = BufReader::new(File::open("foo.txt")?);
407 /// let before = f.stream_position()?;
408 /// f.read_line(&mut String::new())?;
409 /// let after = f.stream_position()?;
411 /// println!("The first line was {} bytes long", after - before);
415 fn stream_position(&mut self) -> io::Result<u64> {
416 let remainder = (self.cap - self.pos) as u64;
417 self.inner.stream_position().map(|pos| {
418 pos.checked_sub(remainder).expect(
419 "overflow when subtracting remaining buffer size from inner stream position",