// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.
// Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer// object, creating another object (Reader or Writer) that also implements// the interface but provides buffering and some help for textual I/O.
package bufioimport ()const (defaultBufSize = 4096)var (ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte")ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune")ErrBufferFull = errors.New("bufio: buffer full")ErrNegativeCount = errors.New("bufio: negative count"))// Buffered input.// Reader implements buffering for an io.Reader object.typeReaderstruct {buf []byterdio.Reader// reader provided by the clientr, wint// buf read and write positionserrerrorlastByteint// last byte read for UnreadByte; -1 means invalidlastRuneSizeint// size of last rune read for UnreadRune; -1 means invalid}constminReadBufferSize = 16constmaxConsecutiveEmptyReads = 100// NewReaderSize returns a new Reader whose buffer has at least the specified// size. If the argument io.Reader is already a Reader with large enough// size, it returns the underlying Reader.func ( io.Reader, int) *Reader {// Is it already a Reader? , := .(*Reader)if && len(.buf) >= {return }if < minReadBufferSize { = minReadBufferSize } := new(Reader) .reset(make([]byte, ), )return}// NewReader returns a new Reader whose buffer has the default size.func ( io.Reader) *Reader {returnNewReaderSize(, defaultBufSize)}// Size returns the size of the underlying buffer in bytes.func ( *Reader) () int { returnlen(.buf) }// Reset discards any buffered data, resets all state, and switches// the buffered reader to read from r.// Calling Reset on the zero value of Reader initializes the internal buffer// to the default size.// Calling b.Reset(b) (that is, resetting a Reader to itself) does nothing.func ( *Reader) ( io.Reader) {// If a Reader r is passed to NewReader, NewReader will return r. // Different layers of code may do that, and then later pass r // to Reset. Avoid infinite recursion in that case.if == {return }if .buf == nil { .buf = make([]byte, defaultBufSize) } .reset(.buf, )}func ( *Reader) ( []byte, io.Reader) { * = Reader{buf: ,rd: ,lastByte: -1,lastRuneSize: -1, }}varerrNegativeRead = errors.New("bufio: reader returned negative count from Read")// fill reads a new chunk into the buffer.func ( *Reader) () {// Slide existing data to beginning.if .r > 0 {copy(.buf, .buf[.r:.w]) .w -= .r .r = 0 }if .w >= len(.buf) {panic("bufio: tried to fill full buffer") }// Read new data: try a limited number of times.for := maxConsecutiveEmptyReads; > 0; -- { , := .rd.Read(.buf[.w:])if < 0 {panic(errNegativeRead) } .w += if != nil { .err = return }if > 0 {return } } .err = io.ErrNoProgress}func ( *Reader) () error { := .err .err = nilreturn}// Peek returns the next n bytes without advancing the reader. The bytes stop// being valid at the next read call. If Peek returns fewer than n bytes, it// also returns an error explaining why the read is short. The error is// ErrBufferFull if n is larger than b's buffer size.//// Calling Peek prevents a UnreadByte or UnreadRune call from succeeding// until the next read operation.func ( *Reader) ( int) ([]byte, error) {if < 0 {returnnil, ErrNegativeCount } .lastByte = -1 .lastRuneSize = -1for .w-.r < && .w-.r < len(.buf) && .err == nil { .fill() // b.w-b.r < len(b.buf) => buffer is not full }if > len(.buf) {return .buf[.r:.w], ErrBufferFull }// 0 <= n <= len(b.buf)varerrorif := .w - .r; < {// not enough data in buffer = = .readErr()if == nil { = ErrBufferFull } }return .buf[.r : .r+], }// Discard skips the next n bytes, returning the number of bytes discarded.//// If Discard skips fewer than n bytes, it also returns an error.// If 0 <= n <= b.Buffered(), Discard is guaranteed to succeed without// reading from the underlying io.Reader.func ( *Reader) ( int) ( int, error) {if < 0 {return0, ErrNegativeCount }if == 0 {return } .lastByte = -1 .lastRuneSize = -1 := for { := .Buffered()if == 0 { .fill() = .Buffered() }if > { = } .r += -= if == 0 {return , nil }if .err != nil {return - , .readErr() } }}// Read reads data into p.// It returns the number of bytes read into p.// The bytes are taken from at most one Read on the underlying Reader,// hence n may be less than len(p).// To read exactly len(p) bytes, use io.ReadFull(b, p).// If the underlying Reader can return a non-zero count with io.EOF,// then this Read method can do so as well; see the [io.Reader] docs.func ( *Reader) ( []byte) ( int, error) { = len()if == 0 {if .Buffered() > 0 {return0, nil }return0, .readErr() }if .r == .w {if .err != nil {return0, .readErr() }iflen() >= len(.buf) {// Large read, empty buffer. // Read directly into p to avoid copy. , .err = .rd.Read()if < 0 {panic(errNegativeRead) }if > 0 { .lastByte = int([-1]) .lastRuneSize = -1 }return , .readErr() }// One read. // Do not use b.fill, which will loop. .r = 0 .w = 0 , .err = .rd.Read(.buf)if < 0 {panic(errNegativeRead) }if == 0 {return0, .readErr() } .w += }// copy as much as we can // Note: if the slice panics here, it is probably because // the underlying reader returned a bad count. See issue 49795. = copy(, .buf[.r:.w]) .r += .lastByte = int(.buf[.r-1]) .lastRuneSize = -1return , nil}// ReadByte reads and returns a single byte.// If no byte is available, returns an error.func ( *Reader) () (byte, error) { .lastRuneSize = -1for .r == .w {if .err != nil {return0, .readErr() } .fill() // buffer is empty } := .buf[.r] .r++ .lastByte = int()return , nil}// UnreadByte unreads the last byte. Only the most recently read byte can be unread.//// UnreadByte returns an error if the most recent method called on the// Reader was not a read operation. Notably, Peek, Discard, and WriteTo are not// considered read operations.func ( *Reader) () error {if .lastByte < 0 || .r == 0 && .w > 0 {returnErrInvalidUnreadByte }// b.r > 0 || b.w == 0if .r > 0 { .r-- } else {// b.r == 0 && b.w == 0 .w = 1 } .buf[.r] = byte(.lastByte) .lastByte = -1 .lastRuneSize = -1returnnil}// ReadRune reads a single UTF-8 encoded Unicode character and returns the// rune and its size in bytes. If the encoded rune is invalid, it consumes one byte// and returns unicode.ReplacementChar (U+FFFD) with a size of 1.func ( *Reader) () ( rune, int, error) {for .r+utf8.UTFMax > .w && !utf8.FullRune(.buf[.r:.w]) && .err == nil && .w-.r < len(.buf) { .fill() // b.w-b.r < len(buf) => buffer is not full } .lastRuneSize = -1if .r == .w {return0, 0, .readErr() } , = rune(.buf[.r]), 1if >= utf8.RuneSelf { , = utf8.DecodeRune(.buf[.r:.w]) } .r += .lastByte = int(.buf[.r-1]) .lastRuneSize = return , , nil}// UnreadRune unreads the last rune. If the most recent method called on// the Reader was not a ReadRune, UnreadRune returns an error. (In this// regard it is stricter than UnreadByte, which will unread the last byte// from any read operation.)func ( *Reader) () error {if .lastRuneSize < 0 || .r < .lastRuneSize {returnErrInvalidUnreadRune } .r -= .lastRuneSize .lastByte = -1 .lastRuneSize = -1returnnil}// Buffered returns the number of bytes that can be read from the current buffer.func ( *Reader) () int { return .w - .r }// ReadSlice reads until the first occurrence of delim in the input,// returning a slice pointing at the bytes in the buffer.// The bytes stop being valid at the next read.// If ReadSlice encounters an error before finding a delimiter,// it returns all the data in the buffer and the error itself (often io.EOF).// ReadSlice fails with error ErrBufferFull if the buffer fills without a delim.// Because the data returned from ReadSlice will be overwritten// by the next I/O operation, most clients should use// ReadBytes or ReadString instead.// ReadSlice returns err != nil if and only if line does not end in delim.func ( *Reader) ( byte) ( []byte, error) { := 0// search start indexfor {// Search buffer.if := bytes.IndexByte(.buf[.r+:.w], ); >= 0 { += = .buf[.r : .r++1] .r += + 1break }// Pending error?if .err != nil { = .buf[.r:.w] .r = .w = .readErr()break }// Buffer full?if .Buffered() >= len(.buf) { .r = .w = .buf = ErrBufferFullbreak } = .w - .r// do not rescan area we scanned before .fill() // buffer is not full }// Handle last byte, if any.if := len() - 1; >= 0 { .lastByte = int([]) .lastRuneSize = -1 }return}// ReadLine is a low-level line-reading primitive. Most callers should use// ReadBytes('\n') or ReadString('\n') instead or use a Scanner.//// ReadLine tries to return a single line, not including the end-of-line bytes.// If the line was too long for the buffer then isPrefix is set and the// beginning of the line is returned. The rest of the line will be returned// from future calls. isPrefix will be false when returning the last fragment// of the line. The returned buffer is only valid until the next call to// ReadLine. ReadLine either returns a non-nil line or it returns an error,// never both.//// The text returned from ReadLine does not include the line end ("\r\n" or "\n").// No indication or error is given if the input ends without a final line end.// Calling UnreadByte after ReadLine will always unread the last byte read// (possibly a character belonging to the line end) even if that byte is not// part of the line returned by ReadLine.func ( *Reader) () ( []byte, bool, error) { , = .ReadSlice('\n')if == ErrBufferFull {// Handle the case where "\r\n" straddles the buffer.iflen() > 0 && [len()-1] == '\r' {// Put the '\r' back on buf and drop it from line. // Let the next call to ReadLine check for "\r\n".if .r == 0 {// should be unreachablepanic("bufio: tried to rewind past start of buffer") } .r-- = [:len()-1] }return , true, nil }iflen() == 0 {if != nil { = nil }return } = nilif [len()-1] == '\n' { := 1iflen() > 1 && [len()-2] == '\r' { = 2 } = [:len()-] }return}// collectFragments reads until the first occurrence of delim in the input. It// returns (slice of full buffers, remaining bytes before delim, total number// of bytes in the combined first two elements, error).// The complete result is equal to// `bytes.Join(append(fullBuffers, finalFragment), nil)`, which has a// length of `totalLen`. The result is structured in this way to allow callers// to minimize allocations and copies.func ( *Reader) ( byte) ( [][]byte, []byte, int, error) {var []byte// Use ReadSlice to look for delim, accumulating full buffers.for {varerror , = .ReadSlice()if == nil { // got final fragmentbreak }if != ErrBufferFull { // unexpected error = break }// Make a copy of the buffer. := bytes.Clone() = append(, ) += len() } += len()return , , , }// ReadBytes reads until the first occurrence of delim in the input,// returning a slice containing the data up to and including the delimiter.// If ReadBytes encounters an error before finding a delimiter,// it returns the data read before the error and the error itself (often io.EOF).// ReadBytes returns err != nil if and only if the returned data does not end in// delim.// For simple uses, a Scanner may be more convenient.func ( *Reader) ( byte) ([]byte, error) { , , , := .collectFragments()// Allocate new buffer to hold the full pieces and the fragment. := make([]byte, ) = 0// Copy full pieces and fragment in.for := range { += copy([:], []) }copy([:], )return , }// ReadString reads until the first occurrence of delim in the input,// returning a string containing the data up to and including the delimiter.// If ReadString encounters an error before finding a delimiter,// it returns the data read before the error and the error itself (often io.EOF).// ReadString returns err != nil if and only if the returned data does not end in// delim.// For simple uses, a Scanner may be more convenient.func ( *Reader) ( byte) (string, error) { , , , := .collectFragments()// Allocate new buffer to hold the full pieces and the fragment.varstrings.Builder .Grow()// Copy full pieces and fragment in.for , := range { .Write() } .Write()return .String(), }// WriteTo implements io.WriterTo.// This may make multiple calls to the Read method of the underlying Reader.// If the underlying reader supports the WriteTo method,// this calls the underlying WriteTo without buffering.func ( *Reader) ( io.Writer) ( int64, error) { .lastByte = -1 .lastRuneSize = -1 , = .writeBuf()if != nil {return }if , := .rd.(io.WriterTo); { , := .WriteTo() += return , }if , := .(io.ReaderFrom); { , := .ReadFrom(.rd) += return , }if .w-.r < len(.buf) { .fill() // buffer not full }for .r < .w {// b.r < b.w => buffer is not empty , := .writeBuf() += if != nil {return , } .fill() // buffer is empty }if .err == io.EOF { .err = nil }return , .readErr()}varerrNegativeWrite = errors.New("bufio: writer returned negative count from Write")// writeBuf writes the Reader's buffer to the writer.func ( *Reader) ( io.Writer) (int64, error) { , := .Write(.buf[.r:.w])if < 0 {panic(errNegativeWrite) } .r += returnint64(), }// buffered output// Writer implements buffering for an io.Writer object.// If an error occurs writing to a Writer, no more data will be// accepted and all subsequent writes, and Flush, will return the error.// After all data has been written, the client should call the// Flush method to guarantee all data has been forwarded to// the underlying io.Writer.typeWriterstruct {errerrorbuf []bytenintwrio.Writer}// NewWriterSize returns a new Writer whose buffer has at least the specified// size. If the argument io.Writer is already a Writer with large enough// size, it returns the underlying Writer.func ( io.Writer, int) *Writer {// Is it already a Writer? , := .(*Writer)if && len(.buf) >= {return }if <= 0 { = defaultBufSize }return &Writer{buf: make([]byte, ),wr: , }}// NewWriter returns a new Writer whose buffer has the default size.// If the argument io.Writer is already a Writer with large enough buffer size,// it returns the underlying Writer.func ( io.Writer) *Writer {returnNewWriterSize(, defaultBufSize)}// Size returns the size of the underlying buffer in bytes.func ( *Writer) () int { returnlen(.buf) }// Reset discards any unflushed buffered data, clears any error, and// resets b to write its output to w.// Calling Reset on the zero value of Writer initializes the internal buffer// to the default size.// Calling w.Reset(w) (that is, resetting a Writer to itself) does nothing.func ( *Writer) ( io.Writer) {// If a Writer w is passed to NewWriter, NewWriter will return w. // Different layers of code may do that, and then later pass w // to Reset. Avoid infinite recursion in that case.if == {return }if .buf == nil { .buf = make([]byte, defaultBufSize) } .err = nil .n = 0 .wr = }// Flush writes any buffered data to the underlying io.Writer.func ( *Writer) () error {if .err != nil {return .err }if .n == 0 {returnnil } , := .wr.Write(.buf[0:.n])if < .n && == nil { = io.ErrShortWrite }if != nil {if > 0 && < .n {copy(.buf[0:.n-], .buf[:.n]) } .n -= .err = return } .n = 0returnnil}// Available returns how many bytes are unused in the buffer.func ( *Writer) () int { returnlen(.buf) - .n }// AvailableBuffer returns an empty buffer with b.Available() capacity.// This buffer is intended to be appended to and// passed to an immediately succeeding Write call.// The buffer is only valid until the next write operation on b.func ( *Writer) () []byte {return .buf[.n:][:0]}// Buffered returns the number of bytes that have been written into the current buffer.func ( *Writer) () int { return .n }// Write writes the contents of p into the buffer.// It returns the number of bytes written.// If nn < len(p), it also returns an error explaining// why the write is short.func ( *Writer) ( []byte) ( int, error) {forlen() > .Available() && .err == nil {varintif .Buffered() == 0 {// Large write, empty buffer. // Write directly from p to avoid copy. , .err = .wr.Write() } else { = copy(.buf[.n:], ) .n += .Flush() } += = [:] }if .err != nil {return , .err } := copy(.buf[.n:], ) .n += += return , nil}// WriteByte writes a single byte.func ( *Writer) ( byte) error {if .err != nil {return .err }if .Available() <= 0 && .Flush() != nil {return .err } .buf[.n] = .n++returnnil}// WriteRune writes a single Unicode code point, returning// the number of bytes written and any error.func ( *Writer) ( rune) ( int, error) {// Compare as uint32 to correctly handle negative runes.ifuint32() < utf8.RuneSelf { = .WriteByte(byte())if != nil {return0, }return1, nil }if .err != nil {return0, .err } := .Available()if < utf8.UTFMax {if .Flush(); .err != nil {return0, .err } = .Available()if < utf8.UTFMax {// Can only happen if buffer is silly small.return .WriteString(string()) } } = utf8.EncodeRune(.buf[.n:], ) .n += return , nil}// WriteString writes a string.// It returns the number of bytes written.// If the count is less than len(s), it also returns an error explaining// why the write is short.func ( *Writer) ( string) (int, error) {vario.StringWriter := true := 0forlen() > .Available() && .err == nil {varintif .Buffered() == 0 && == nil && {// Check at most once whether b.wr is a StringWriter. , = .wr.(io.StringWriter) }if .Buffered() == 0 && {// Large write, empty buffer, and the underlying writer supports // WriteString: forward the write to the underlying StringWriter. // This avoids an extra copy. , .err = .WriteString() } else { = copy(.buf[.n:], ) .n += .Flush() } += = [:] }if .err != nil {return , .err } := copy(.buf[.n:], ) .n += += return , nil}// ReadFrom implements io.ReaderFrom. If the underlying writer// supports the ReadFrom method, this calls the underlying ReadFrom.// If there is buffered data and an underlying ReadFrom, this fills// the buffer and writes it before calling ReadFrom.func ( *Writer) ( io.Reader) ( int64, error) {if .err != nil {return0, .err } , := .wr.(io.ReaderFrom)varintfor {if .Available() == 0 {if := .Flush(); != nil {return , } }if && .Buffered() == 0 { , := .ReadFrom() .err = += return , } := 0for < maxConsecutiveEmptyReads { , = .Read(.buf[.n:])if != 0 || != nil {break } ++ }if == maxConsecutiveEmptyReads {return , io.ErrNoProgress } .n += += int64()if != nil {break } }if == io.EOF {// If we filled the buffer exactly, flush preemptively.if .Available() == 0 { = .Flush() } else { = nil } }return , }// buffered input and output// ReadWriter stores pointers to a Reader and a Writer.// It implements io.ReadWriter.typeReadWriterstruct { *Reader *Writer}// NewReadWriter allocates a new ReadWriter that dispatches to r and w.func ( *Reader, *Writer) *ReadWriter {return &ReadWriter{, }}
The pages are generated with Goldsv0.6.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.