// ReaderFrom is the interface that wraps the ReadFrom method. // // ReadFrom reads data from r until EOF or error. // The return value n is the number of bytes read. // Any error except io.EOF encountered during the read is also returned. // // The Copy function uses ReaderFrom if available. type ReaderFrom interface { ReadFrom(r Reader) (n int64, err error) }
// WriterTo is the interface that wraps the WriteTo method. // // WriteTo writes data to w until there's no more data to write or // when an error occurs. The return value n is the number of bytes // written. Any error encountered during the write is also returned. // // The Copy function uses WriterTo if available. type WriterTo interface { WriteTo(w Writer) (n int64, err error) }
// ReaderAt is the interface that wraps the basic ReadAt method. // // ReadAt reads len(p) bytes into p starting at offset off in the // underlying input source. It returns the number of bytes // read (0 <= n <= len(p)) and any error encountered. // // When ReadAt returns n < len(p), it returns a non-nil error // explaining why more bytes were not returned. In this respect, // ReadAt is stricter than Read. // // Even if ReadAt returns n < len(p), it may use all of p as scratch // space during the call. If some data is available but not len(p) bytes, // ReadAt blocks until either all the data is available or an error occurs. // In this respect ReadAt is different from Read. // // If the n = len(p) bytes returned by ReadAt are at the end of the // input source, ReadAt may return either err == EOF or err == nil. // // If ReadAt is reading from an input source with a seek offset, // ReadAt should not affect nor be affected by the underlying // seek offset. // // Clients of ReadAt can execute parallel ReadAt calls on the // same input source. // // Implementations must not retain p. type ReaderAt interface { ReadAt(p []byte, off int64) (n int, err error) }
// WriterAt is the interface that wraps the basic WriteAt method. // // WriteAt writes len(p) bytes from p to the underlying data stream // at offset off. It returns the number of bytes written from p (0 <= n <= len(p)) // and any error encountered that caused the write to stop early. // WriteAt must return a non-nil error if it returns n < len(p). // // If WriteAt is writing to a destination with a seek offset, // WriteAt should not affect nor be affected by the underlying // seek offset. // // Clients of WriteAt can execute parallel WriteAt calls on the same // destination if the ranges do not overlap. // // Implementations must not retain p. type WriterAt interface { WriteAt(p []byte, off int64) (n int, err error) }
从指定偏移量开始读取或者写
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// StringWriter is the interface that wraps the WriteString method. type StringWriter interface { WriteString(s string) (n int, err error) }
// WriteString writes the contents of the string s to w, which accepts a slice of bytes. // If w implements StringWriter, its WriteString method is invoked directly. // Otherwise, w.Write is called exactly once. funcWriteString(w Writer, s string)(n int, err error) { if sw, ok := w.(StringWriter); ok { return sw.WriteString(s) } return w.Write([]byte(s)) }
funcReadAtLeast(r Reader, buf []byte, min int)(n int, err error) { iflen(buf) < min { return0, ErrShortBuffer } for n < min && err == nil { var nn int nn, err = r.Read(buf[n:]) n += nn } if n >= min { err = nil } elseif n > 0 && err == EOF { err = ErrUnexpectedEOF } return }
funcCopyN(dst Writer, src Reader, n int64)(written int64, err error) { written, err = Copy(dst, LimitReader(src, n)) if written == n { return n, nil } if written < n && err == nil { // src stopped early; must have been EOF. err = EOF } return }
funccopyBuffer(dst Writer, src Reader, buf []byte)(written int64, err error) { // If the reader has a WriteTo method, use it to do the copy. // Avoids an allocation and a copy. if wt, ok := src.(WriterTo); ok { return wt.WriteTo(dst) } // Similarly, if the writer has a ReadFrom method, use it to do the copy. if rt, ok := dst.(ReaderFrom); ok { return rt.ReadFrom(src) } if buf == nil { size := 32 * 1024 if l, ok := src.(*LimitedReader); ok && int64(size) > l.N { if l.N < 1 { size = 1 } else { size = int(l.N) } } buf = make([]byte, size) } for { nr, er := src.Read(buf) if nr > 0 { nw, ew := dst.Write(buf[0:nr]) if nw > 0 { written += int64(nw) } if ew != nil { err = ew break } if nr != nw { err = ErrShortWrite break } } if er != nil { if er != EOF { err = er } break } } return written, err }
CopyN(dst Writer, src Reader, n int64) (written int64, err error)调用Copy方法并包装当前reader为LimitReader
// LimitReader returns a Reader that reads from r // but stops with EOF after n bytes. // The underlying implementation is a *LimitedReader. funcLimitReader(r Reader, n int64)Reader { return &LimitedReader{r, n} }
// A LimitedReader reads from R but limits the amount of // data returned to just N bytes. Each call to Read // updates N to reflect the new amount remaining. // Read returns EOF when N <= 0 or when the underlying R returns EOF. type LimitedReader struct { R Reader // underlying reader N int64// max bytes remaining }
// NewSectionReader returns a SectionReader that reads from r // starting at offset off and stops with EOF after n bytes. funcNewSectionReader(r ReaderAt, off int64, n int64) *SectionReader { return &SectionReader{r, off, off, off + n} }
// SectionReader implements Read, Seek, and ReadAt on a section // of an underlying ReaderAt. type SectionReader struct { r ReaderAt base int64 off int64 limit int64 }
func(s *SectionReader)Read(p []byte)(n int, err error) { if s.off >= s.limit { return0, EOF } if max := s.limit - s.off; int64(len(p)) > max { p = p[0:max] } n, err = s.r.ReadAt(p, s.off) s.off += int64(n) return }
var errWhence = errors.New("Seek: invalid whence") var errOffset = errors.New("Seek: invalid offset")
func(s *SectionReader)ReadAt(p []byte, off int64)(n int, err error) { if off < 0 || off >= s.limit-s.base { return0, EOF } off += s.base if max := s.limit - off; int64(len(p)) > max { p = p[0:max] n, err = s.r.ReadAt(p, off) if err == nil { err = EOF } return n, err } return s.r.ReadAt(p, off) }
// Size returns the size of the section in bytes. func(s *SectionReader)Size()int64 { return s.limit - s.base }
(s *SectionReader) ReadAt(p []byte, off int64) (n int, err error)从指定位置开始读取,如果当前偏移量超出了限制,就返回EOF,并且如果结尾的数量小于当前buf的大小,就对buf进行重新切片,再调用reader的ReadAt()方法防止超出。
// TeeReader returns a Reader that writes to w what it reads from r. // All reads from r performed through it are matched with // corresponding writes to w. There is no internal buffering - // the write must complete before the read completes. // Any error encountered while writing is reported as a read error. funcTeeReader(r Reader, w Writer)Reader { return &teeReader{r, w} }
type teeReader struct { r Reader w Writer }
func(t *teeReader)Read(p []byte)(n int, err error) { n, err = t.r.Read(p) if n > 0 { if n, err := t.w.Write(p[:n]); err != nil { return n, err } } return }
func(mr *multiReader)Read(p []byte)(n int, err error) { forlen(mr.readers) > 0 { // Optimization to flatten nested multiReaders (Issue 13558). iflen(mr.readers) == 1 { if r, ok := mr.readers[0].(*multiReader); ok { mr.readers = r.readers continue } } n, err = mr.readers[0].Read(p) if err == EOF { // Use eofReader instead of nil to avoid nil panic // after performing flatten (Issue 18232). mr.readers[0] = eofReader{} // permit earlier GC mr.readers = mr.readers[1:] } if n > 0 || err != EOF { if err == EOF && len(mr.readers) > 0 { // Don't return EOF yet. More readers remain. err = nil } return } } return0, EOF }
// MultiReader returns a Reader that's the logical concatenation of // the provided input readers. They're read sequentially. Once all // inputs have returned EOF, Read will return EOF. If any of the readers // return a non-nil, non-EOF error, Read will return that error. funcMultiReader(readers ...Reader)Reader { r := make([]Reader, len(readers)) copy(r, readers) return &multiReader{r} }
func(t *multiWriter)Write(p []byte)(n int, err error) { for _, w := range t.writers { n, err = w.Write(p) if err != nil { return } if n != len(p) { err = ErrShortWrite return } } returnlen(p), nil }
var _ StringWriter = (*multiWriter)(nil)
func(t *multiWriter)WriteString(s string)(n int, err error) { var p []byte// lazily initialized if/when needed for _, w := range t.writers { if sw, ok := w.(StringWriter); ok { n, err = sw.WriteString(s) } else { if p == nil { p = []byte(s) } n, err = w.Write(p) } if err != nil { return } if n != len(s) { err = ErrShortWrite return } } returnlen(s), nil }
// MultiWriter creates a writer that duplicates its writes to all the // provided writers, similar to the Unix tee(1) command. // // Each write is written to each listed writer, one at a time. // If a listed writer returns an error, that overall write operation // stops and returns the error; it does not continue down the list. funcMultiWriter(writers ...Writer)Writer { allWriters := make([]Writer, 0, len(writers)) for _, w := range writers { if mw, ok := w.(*multiWriter); ok { allWriters = append(allWriters, mw.writers...) } else { allWriters = append(allWriters, w) } } return &multiWriter{allWriters} }
// atomicError is a type-safe atomic value for errors. // We use a struct{ error } to ensure consistent use of a concrete type. type atomicError struct{ v atomic.Value }
for once := true; once || len(b) > 0; once = false { select { case p.wrCh <- b: nw := <-p.rdCh b = b[nw:] n += nw case <-p.done: return n, p.writeCloseError() } } return n, nil }