Skip to main content

alloc/io/buffered/
bufreader.rs

1mod buffer;
2
3use buffer::Buffer;
4
5use crate::fmt;
6use crate::io::{
7    self, BorrowedCursor, BufRead, DEFAULT_BUF_SIZE, IoSliceMut, Read, Seek, SeekFrom, SizeHint,
8    SpecReadByte, uninlined_slow_read_byte,
9};
10use crate::string::String;
11use crate::vec::Vec;
12
13/// The `BufReader<R>` struct adds buffering to any reader.
14///
15/// It can be excessively inefficient to work directly with a [`Read`] instance.
16/// For example, every call to [`read`][`TcpStream::read`] on [`TcpStream`]
17/// results in a system call. A `BufReader<R>` performs large, infrequent reads on
18/// the underlying [`Read`] and maintains an in-memory buffer of the results.
19///
20/// `BufReader<R>` can improve the speed of programs that make *small* and
21/// *repeated* read calls to the same file or network socket. It does not
22/// help when reading very large amounts at once, or reading just one or a few
23/// times. It also provides no advantage when reading from a source that is
24/// already in memory, like a <code>[Vec]\<u8></code>.
25///
26/// When the `BufReader<R>` is dropped, the contents of its buffer will be
27/// discarded. Creating multiple instances of a `BufReader<R>` on the same
28/// stream can cause data loss. Reading from the underlying reader after
29/// unwrapping the `BufReader<R>` with [`BufReader::into_inner`] can also cause
30/// data loss.
31///
32// FIXME(#74481): Hard-links required to link from `alloc` to `std`
33/// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read
34/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
35///
36/// # Examples
37///
38/// ```no_run
39/// use std::io::prelude::*;
40/// use std::io::BufReader;
41/// use std::fs::File;
42///
43/// fn main() -> std::io::Result<()> {
44///     let f = File::open("log.txt")?;
45///     let mut reader = BufReader::new(f);
46///
47///     let mut line = String::new();
48///     let len = reader.read_line(&mut line)?;
49///     println!("First line is {len} bytes long");
50///     Ok(())
51/// }
52/// ```
53#[stable(feature = "rust1", since = "1.0.0")]
54#[cfg_attr(not(test), rustc_diagnostic_item = "IoBufReader")]
55pub struct BufReader<R: ?Sized> {
56    buf: Buffer,
57    inner: R,
58}
59
60impl<R: Read> BufReader<R> {
61    /// Creates a new `BufReader<R>` with a default buffer capacity. The default is currently 8 KiB,
62    /// but may change in the future.
63    ///
64    /// # Examples
65    ///
66    /// ```no_run
67    /// use std::io::BufReader;
68    /// use std::fs::File;
69    ///
70    /// fn main() -> std::io::Result<()> {
71    ///     let f = File::open("log.txt")?;
72    ///     let reader = BufReader::new(f);
73    ///     Ok(())
74    /// }
75    /// ```
76    #[cfg(not(no_global_oom_handling))]
77    #[stable(feature = "rust1", since = "1.0.0")]
78    pub fn new(inner: R) -> BufReader<R> {
79        BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
80    }
81
82    /// Attempts to allocate an internal buffer, _then_ calls the provided function
83    /// to retrieve the inner reader `R`.
84    #[doc(hidden)]
85    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
86    #[inline]
87    pub fn try_new_with(f: impl FnOnce() -> io::Result<R>) -> io::Result<Self> {
88        let buf = Buffer::try_with_capacity(DEFAULT_BUF_SIZE)?;
89        let inner = f()?;
90        Ok(Self { inner, buf })
91    }
92
93    /// Creates a new `BufReader<R>` with the specified buffer capacity.
94    ///
95    /// # Examples
96    ///
97    /// Creating a buffer with ten bytes of capacity:
98    ///
99    /// ```no_run
100    /// use std::io::BufReader;
101    /// use std::fs::File;
102    ///
103    /// fn main() -> std::io::Result<()> {
104    ///     let f = File::open("log.txt")?;
105    ///     let reader = BufReader::with_capacity(10, f);
106    ///     Ok(())
107    /// }
108    /// ```
109    #[cfg(not(no_global_oom_handling))]
110    #[stable(feature = "rust1", since = "1.0.0")]
111    pub fn with_capacity(capacity: usize, inner: R) -> BufReader<R> {
112        BufReader { inner, buf: Buffer::with_capacity(capacity) }
113    }
114}
115
116impl<R: Read + ?Sized> BufReader<R> {
117    /// Attempt to look ahead `n` bytes.
118    ///
119    /// `n` must be less than or equal to `capacity`.
120    ///
121    /// The returned slice may be less than `n` bytes long if
122    /// end of file is reached.
123    ///
124    /// After calling this method, you may call [`consume`](BufRead::consume)
125    /// with a value less than or equal to `n` to advance over some or all of
126    /// the returned bytes.
127    ///
128    /// ## Examples
129    ///
130    /// ```rust
131    /// #![feature(bufreader_peek)]
132    /// use std::io::{Read, BufReader};
133    ///
134    /// let mut bytes = &b"oh, hello there"[..];
135    /// let mut rdr = BufReader::with_capacity(6, &mut bytes);
136    /// assert_eq!(rdr.peek(2).unwrap(), b"oh");
137    /// let mut buf = [0; 4];
138    /// rdr.read(&mut buf[..]).unwrap();
139    /// assert_eq!(&buf, b"oh, ");
140    /// assert_eq!(rdr.peek(5).unwrap(), b"hello");
141    /// let mut s = String::new();
142    /// rdr.read_to_string(&mut s).unwrap();
143    /// assert_eq!(&s, "hello there");
144    /// assert_eq!(rdr.peek(1).unwrap().len(), 0);
145    /// ```
146    #[unstable(feature = "bufreader_peek", issue = "128405")]
147    pub fn peek(&mut self, n: usize) -> io::Result<&[u8]> {
148        assert!(n <= self.capacity());
149        while n > self.buf.buffer().len() {
150            if self.buf.pos() > 0 {
151                self.buf.backshift();
152            }
153            let new = self.buf.read_more(&mut self.inner)?;
154            if new == 0 {
155                // end of file, no more bytes to read
156                return Ok(&self.buf.buffer()[..]);
157            }
158            debug_assert_eq!(self.buf.pos(), 0);
159        }
160        Ok(&self.buf.buffer()[..n])
161    }
162}
163
164impl<R: ?Sized> BufReader<R> {
165    /// Gets a reference to the underlying reader.
166    ///
167    /// It is inadvisable to directly read from the underlying reader.
168    ///
169    /// # Examples
170    ///
171    /// ```no_run
172    /// use std::io::BufReader;
173    /// use std::fs::File;
174    ///
175    /// fn main() -> std::io::Result<()> {
176    ///     let f1 = File::open("log.txt")?;
177    ///     let reader = BufReader::new(f1);
178    ///
179    ///     let f2 = reader.get_ref();
180    ///     Ok(())
181    /// }
182    /// ```
183    #[stable(feature = "rust1", since = "1.0.0")]
184    pub fn get_ref(&self) -> &R {
185        &self.inner
186    }
187
188    /// Gets a mutable reference to the underlying reader.
189    ///
190    /// It is inadvisable to directly read from the underlying reader.
191    ///
192    /// # Examples
193    ///
194    /// ```no_run
195    /// use std::io::BufReader;
196    /// use std::fs::File;
197    ///
198    /// fn main() -> std::io::Result<()> {
199    ///     let f1 = File::open("log.txt")?;
200    ///     let mut reader = BufReader::new(f1);
201    ///
202    ///     let f2 = reader.get_mut();
203    ///     Ok(())
204    /// }
205    /// ```
206    #[stable(feature = "rust1", since = "1.0.0")]
207    pub fn get_mut(&mut self) -> &mut R {
208        &mut self.inner
209    }
210
211    /// Returns a reference to the internally buffered data.
212    ///
213    /// Unlike [`fill_buf`], this will not attempt to fill the buffer if it is empty.
214    ///
215    /// [`fill_buf`]: BufRead::fill_buf
216    ///
217    /// # Examples
218    ///
219    /// ```no_run
220    /// use std::io::{BufReader, BufRead};
221    /// use std::fs::File;
222    ///
223    /// fn main() -> std::io::Result<()> {
224    ///     let f = File::open("log.txt")?;
225    ///     let mut reader = BufReader::new(f);
226    ///     assert!(reader.buffer().is_empty());
227    ///
228    ///     if reader.fill_buf()?.len() > 0 {
229    ///         assert!(!reader.buffer().is_empty());
230    ///     }
231    ///     Ok(())
232    /// }
233    /// ```
234    #[stable(feature = "bufreader_buffer", since = "1.37.0")]
235    pub fn buffer(&self) -> &[u8] {
236        self.buf.buffer()
237    }
238
239    /// Returns the number of bytes the internal buffer can hold at once.
240    ///
241    /// # Examples
242    ///
243    /// ```no_run
244    /// use std::io::{BufReader, BufRead};
245    /// use std::fs::File;
246    ///
247    /// fn main() -> std::io::Result<()> {
248    ///     let f = File::open("log.txt")?;
249    ///     let mut reader = BufReader::new(f);
250    ///
251    ///     let capacity = reader.capacity();
252    ///     let buffer = reader.fill_buf()?;
253    ///     assert!(buffer.len() <= capacity);
254    ///     Ok(())
255    /// }
256    /// ```
257    #[stable(feature = "buffered_io_capacity", since = "1.46.0")]
258    pub fn capacity(&self) -> usize {
259        self.buf.capacity()
260    }
261
262    /// Unwraps this `BufReader<R>`, returning the underlying reader.
263    ///
264    /// Note that any leftover data in the internal buffer is lost. Therefore,
265    /// a following read from the underlying reader may lead to data loss.
266    ///
267    /// # Examples
268    ///
269    /// ```no_run
270    /// use std::io::BufReader;
271    /// use std::fs::File;
272    ///
273    /// fn main() -> std::io::Result<()> {
274    ///     let f1 = File::open("log.txt")?;
275    ///     let reader = BufReader::new(f1);
276    ///
277    ///     let f2 = reader.into_inner();
278    ///     Ok(())
279    /// }
280    /// ```
281    #[stable(feature = "rust1", since = "1.0.0")]
282    pub fn into_inner(self) -> R
283    where
284        R: Sized,
285    {
286        self.inner
287    }
288
289    /// Invalidates all data in the internal buffer.
290    #[inline]
291    #[doc(hidden)]
292    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
293    pub fn discard_buffer(&mut self) {
294        self.buf.discard_buffer()
295    }
296}
297
298// This is only used by a test which asserts that the initialization-tracking is correct.
299impl<R: ?Sized> BufReader<R> {
300    #[doc(hidden)]
301    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
302    #[allow(missing_docs)]
303    pub fn initialized(&self) -> bool {
304        self.buf.initialized()
305    }
306}
307
308impl<R: ?Sized + Seek> BufReader<R> {
309    /// Seeks relative to the current position. If the new position lies within the buffer,
310    /// the buffer will not be flushed, allowing for more efficient seeks.
311    /// This method does not return the location of the underlying reader, so the caller
312    /// must track this information themselves if it is required.
313    #[stable(feature = "bufreader_seek_relative", since = "1.53.0")]
314    pub fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
315        let pos = self.buf.pos() as u64;
316        if offset < 0 {
317            if let Some(_) = pos.checked_sub((-offset) as u64) {
318                self.buf.unconsume((-offset) as usize);
319                return Ok(());
320            }
321        } else if let Some(new_pos) = pos.checked_add(offset as u64) {
322            if new_pos <= self.buf.filled() as u64 {
323                self.buf.consume(offset as usize);
324                return Ok(());
325            }
326        }
327
328        self.seek(SeekFrom::Current(offset)).map(drop)
329    }
330}
331
332#[doc(hidden)]
333#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
334impl<R> SpecReadByte for BufReader<R>
335where
336    Self: Read,
337{
338    #[inline]
339    fn spec_read_byte(&mut self) -> Option<io::Result<u8>> {
340        let mut byte = 0;
341        if self.buf.consume_with(1, |claimed| byte = claimed[0]) {
342            return Some(Ok(byte));
343        }
344
345        // Fallback case, only reached once per buffer refill.
346        uninlined_slow_read_byte(self)
347    }
348}
349
350#[stable(feature = "rust1", since = "1.0.0")]
351impl<R: ?Sized + Read> Read for BufReader<R> {
352    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
353        // If we don't have any buffered data and we're doing a massive read
354        // (larger than our internal buffer), bypass our internal buffer
355        // entirely.
356        if self.buf.pos() == self.buf.filled() && buf.len() >= self.capacity() {
357            self.discard_buffer();
358            return self.inner.read(buf);
359        }
360        let mut rem = self.fill_buf()?;
361        let nread = rem.read(buf)?;
362        self.consume(nread);
363        Ok(nread)
364    }
365
366    fn read_buf(&mut self, mut cursor: BorrowedCursor<'_, u8>) -> io::Result<()> {
367        // If we don't have any buffered data and we're doing a massive read
368        // (larger than our internal buffer), bypass our internal buffer
369        // entirely.
370        if self.buf.pos() == self.buf.filled() && cursor.capacity() >= self.capacity() {
371            self.discard_buffer();
372            return self.inner.read_buf(cursor);
373        }
374
375        let prev = cursor.written();
376
377        let mut rem = self.fill_buf()?;
378        rem.read_buf(cursor.reborrow())?; // actually never fails
379
380        self.consume(cursor.written() - prev); //slice impl of read_buf known to never unfill buf
381
382        Ok(())
383    }
384
385    // Small read_exacts from a BufReader are extremely common when used with a deserializer.
386    // The default implementation calls read in a loop, which results in surprisingly poor code
387    // generation for the common path where the buffer has enough bytes to fill the passed-in
388    // buffer.
389    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
390        if self.buf.consume_with(buf.len(), |claimed| buf.copy_from_slice(claimed)) {
391            return Ok(());
392        }
393
394        crate::io::default_read_exact(self, buf)
395    }
396
397    fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_, u8>) -> io::Result<()> {
398        if self.buf.consume_with(cursor.capacity(), |claimed| cursor.append(claimed)) {
399            return Ok(());
400        }
401
402        crate::io::default_read_buf_exact(self, cursor)
403    }
404
405    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
406        let total_len = bufs.iter().map(|b| b.len()).sum::<usize>();
407        if self.buf.pos() == self.buf.filled() && total_len >= self.capacity() {
408            self.discard_buffer();
409            return self.inner.read_vectored(bufs);
410        }
411        let mut rem = self.fill_buf()?;
412        let nread = rem.read_vectored(bufs)?;
413
414        self.consume(nread);
415        Ok(nread)
416    }
417
418    fn is_read_vectored(&self) -> bool {
419        self.inner.is_read_vectored()
420    }
421
422    // The inner reader might have an optimized `read_to_end`. Drain our buffer and then
423    // delegate to the inner implementation.
424    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
425        let inner_buf = self.buffer();
426        buf.try_reserve(inner_buf.len())?;
427
428        cfg_select! {
429            no_global_oom_handling => {
430                buf.try_extend_from_slice_of_bytes(inner_buf)?;
431            }
432            _ => {
433                buf.extend_from_slice(inner_buf);
434            }
435        }
436
437        let nread = inner_buf.len();
438        self.discard_buffer();
439        Ok(nread + self.inner.read_to_end(buf)?)
440    }
441
442    // The inner reader might have an optimized `read_to_end`. Drain our buffer and then
443    // delegate to the inner implementation.
444    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
445        // In the general `else` case below we must read bytes into a side buffer, check
446        // that they are valid UTF-8, and then append them to `buf`. This requires a
447        // potentially large memcpy.
448        //
449        // If `buf` is empty--the most common case--we can leverage `append_to_string`
450        // to read directly into `buf`'s internal byte buffer, saving an allocation and
451        // a memcpy.
452        if buf.is_empty() {
453            // `append_to_string`'s safety relies on the buffer only being appended to since
454            // it only checks the UTF-8 validity of new data. If there were existing content in
455            // `buf` then an untrustworthy reader (i.e. `self.inner`) could not only append
456            // bytes but also modify existing bytes and render them invalid. On the other hand,
457            // if `buf` is empty then by definition any writes must be appends and
458            // `append_to_string` will validate all of the new bytes.
459            unsafe { crate::io::append_to_string(buf, |b| self.read_to_end(b)) }
460        } else {
461            // We cannot append our byte buffer directly onto the `buf` String as there could
462            // be an incomplete UTF-8 sequence that has only been partially read. We must read
463            // everything into a side buffer first and then call `from_utf8` on the complete
464            // buffer.
465            let mut bytes = Vec::new();
466            self.read_to_end(&mut bytes)?;
467            let string = crate::str::from_utf8(&bytes).map_err(|_| io::Error::INVALID_UTF8)?;
468
469            cfg_select! {
470                no_global_oom_handling => {
471                    buf.try_push_str(string)?;
472                }
473                _ => {
474                    buf.push_str(string);
475                }
476            }
477
478            Ok(string.len())
479        }
480    }
481}
482
483#[stable(feature = "rust1", since = "1.0.0")]
484impl<R: ?Sized + Read> BufRead for BufReader<R> {
485    fn fill_buf(&mut self) -> io::Result<&[u8]> {
486        self.buf.fill_buf(&mut self.inner)
487    }
488
489    fn consume(&mut self, amt: usize) {
490        self.buf.consume(amt)
491    }
492}
493
494#[stable(feature = "rust1", since = "1.0.0")]
495impl<R> fmt::Debug for BufReader<R>
496where
497    R: ?Sized + fmt::Debug,
498{
499    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
500        fmt.debug_struct("BufReader")
501            .field("reader", &&self.inner)
502            .field(
503                "buffer",
504                &format_args!("{}/{}", self.buf.filled() - self.buf.pos(), self.capacity()),
505            )
506            .finish()
507    }
508}
509
510#[stable(feature = "rust1", since = "1.0.0")]
511impl<R: ?Sized + Seek> Seek for BufReader<R> {
512    /// Seek to an offset, in bytes, in the underlying reader.
513    ///
514    /// The position used for seeking with <code>[SeekFrom::Current]\(_)</code> is the
515    /// position the underlying reader would be at if the `BufReader<R>` had no
516    /// internal buffer.
517    ///
518    /// Seeking always discards the internal buffer, even if the seek position
519    /// would otherwise fall within it. This guarantees that calling
520    /// [`BufReader::into_inner()`] immediately after a seek yields the underlying reader
521    /// at the same position.
522    ///
523    /// To seek without discarding the internal buffer, use [`BufReader::seek_relative`].
524    ///
525    /// See [`std::io::Seek`] for more details.
526    ///
527    /// Note: In the edge case where you're seeking with <code>[SeekFrom::Current]\(n)</code>
528    /// where `n` minus the internal buffer length overflows an `i64`, two
529    /// seeks will be performed instead of one. If the second seek returns
530    /// [`Err`], the underlying reader will be left at the same position it would
531    /// have if you called `seek` with <code>[SeekFrom::Current]\(0)</code>.
532    ///
533    /// [`std::io::Seek`]: Seek
534    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
535        let result: u64;
536        if let SeekFrom::Current(n) = pos {
537            let remainder = (self.buf.filled() - self.buf.pos()) as i64;
538            // it should be safe to assume that remainder fits within an i64 as the alternative
539            // means we managed to allocate 8 exbibytes and that's absurd.
540            // But it's not out of the realm of possibility for some weird underlying reader to
541            // support seeking by i64::MIN so we need to handle underflow when subtracting
542            // remainder.
543            if let Some(offset) = n.checked_sub(remainder) {
544                result = self.inner.seek(SeekFrom::Current(offset))?;
545            } else {
546                // seek backwards by our remainder, and then by the offset
547                self.inner.seek(SeekFrom::Current(-remainder))?;
548                self.discard_buffer();
549                result = self.inner.seek(SeekFrom::Current(n))?;
550            }
551        } else {
552            // Seeking with Start/End doesn't care about our buffer length.
553            result = self.inner.seek(pos)?;
554        }
555        self.discard_buffer();
556        Ok(result)
557    }
558
559    /// Returns the current seek position from the start of the stream.
560    ///
561    /// The value returned is equivalent to `self.seek(SeekFrom::Current(0))`
562    /// but does not flush the internal buffer. Due to this optimization the
563    /// function does not guarantee that calling `.into_inner()` immediately
564    /// afterwards will yield the underlying reader at the same position. Use
565    /// [`BufReader::seek`] instead if you require that guarantee.
566    ///
567    /// # Panics
568    ///
569    /// This function will panic if the position of the inner reader is smaller
570    /// than the amount of buffered data. That can happen if the inner reader
571    /// has an incorrect implementation of [`Seek::stream_position`], or if the
572    /// position has gone out of sync due to calling [`Seek::seek`] directly on
573    /// the underlying reader.
574    ///
575    /// # Example
576    ///
577    /// ```no_run
578    /// use std::{
579    ///     io::{self, BufRead, BufReader, Seek},
580    ///     fs::File,
581    /// };
582    ///
583    /// fn main() -> io::Result<()> {
584    ///     let mut f = BufReader::new(File::open("foo.txt")?);
585    ///
586    ///     let before = f.stream_position()?;
587    ///     f.read_line(&mut String::new())?;
588    ///     let after = f.stream_position()?;
589    ///
590    ///     println!("The first line was {} bytes long", after - before);
591    ///     Ok(())
592    /// }
593    /// ```
594    fn stream_position(&mut self) -> io::Result<u64> {
595        let remainder = (self.buf.filled() - self.buf.pos()) as u64;
596        self.inner.stream_position().map(|pos| {
597            pos.checked_sub(remainder).expect(
598                "overflow when subtracting remaining buffer size from inner stream position",
599            )
600        })
601    }
602
603    /// Seeks relative to the current position.
604    ///
605    /// If the new position lies within the buffer, the buffer will not be
606    /// flushed, allowing for more efficient seeks. This method does not return
607    /// the location of the underlying reader, so the caller must track this
608    /// information themselves if it is required.
609    fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
610        self.seek_relative(offset)
611    }
612}
613
614#[doc(hidden)]
615#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
616impl<T: ?Sized> SizeHint for BufReader<T> {
617    #[inline]
618    fn lower_bound(&self) -> usize {
619        SizeHint::lower_bound(self.get_ref()) + self.buffer().len()
620    }
621
622    #[inline]
623    fn upper_bound(&self) -> Option<usize> {
624        SizeHint::upper_bound(self.get_ref()).and_then(|up| self.buffer().len().checked_add(up))
625    }
626}