io 规范库中外围是要了解 io.Readerio.Writer 两个接口

// Reader 其实就是封装了下Read函数// Read函数冀望读取 len(p) bytes到 p 中,并返回理论读取的长度,即便数据有余 len(p) // 也会立刻返回;只有读取到的数据长度大于0,就要返回 err = nil; 如果没有可读取的数据,则返回 0, EOF; Read不容许呈现 0,nil 这样的返回值type Reader interface {    Read(p []byte) (n int, err error)}// Reader 其实是封装了下Writer函数// Write 就是将 p 中保留的数据写入到内部结构体,并返回理论写入的数据// 同Read一样,返回值不能是 0, nil; 并且Write函数中不能扭转原始数据,哪怕长期扭转也不容许type Writer interface {    Write(p []byte) (n int, err error)}

围绕io.Reader/Writer,有几个罕用的实现:

  • net.Conn, os.Stdin, os.File: 网络、规范输入输出、文件的流读取
  • strings.Reader: 把字符串形象成Reader
  • bytes.Reader: 把[]byte形象成Reader
  • bytes.Buffer: 把[]byte形象成Reader和Writer
  • bufio.Reader/Writer: 形象成带缓冲的流读取(比方按行读写)
    strings.Reader 源码举例剖析:

    // 当然 string.Reader 不仅仅实现了io.Reader接口,还反对很多// A Reader implements the io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner,// io.RuneReader, io.RuneScanner, io.Seeker, and io.WriterTo interfaces by reading// from a string.// The zero value for Reader operates like a Reader of an empty string.type Reader struct {  s        string  i        int64 // 指向当初读取的地位  prevRune int   // index of previous rune; or < 0}// Read implements the io.Reader interface.func (r *Reader) Read(b []byte) (n int, err error) {  // 曾经读到字符串开端,间接返回 io.EOF  if r.i >= int64(len(r.s)) {      return 0, io.EOF  }   // 因为是依照byte读的,所以这个标记位无意义  r.prevRune = -1  // 读取数据  n = copy(b, r.s[r.i:])  // 挪动读取地位指针,向后偏移理论读取的量  r.i += int64(n)  return}

    当很多io相干的操作,比方读写文件、读写网络数据等场景都实现了 Write、Read 接口,那么很多跨io的操作就能够无缝实现,比方将网络读取的数据间接写入文件

    // Copy 从 src 拷贝数据到 dst,直到遇到 EOF,或者产生谬误// 如果 src 中实现了 WriterTo 接口,则调用 src.WriteTo(dst)// 如果 dst 中实现了 ReaderFrom 接口,则调用 dst.ReadFrom(src)func Copy(dst Writer, src Reader) (written int64, err error) {  return copyBuffer(dst, src, nil)}// 这个函数与Copy的区别就是须要咱们本人提供buf缓冲区func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {  if buf != nil && len(buf) == 0 {      panic("empty buffer in CopyBuffer")  }  return copyBuffer(dst, src, buf)}// copyBuffer 是 Copy 和 CopyBuffer 的具体实现func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {  // 如果 Reader 实现了 WriteTo 办法, 则间接调用它是先数据拷贝  if wt, ok := src.(WriterTo); ok {      return wt.WriteTo(dst)  }  // 如果 Writer 实现了 ReaderFrom 办法, 则间接调用它是先数据拷贝  if rt, ok := dst.(ReaderFrom); ok {      return rt.ReadFrom(src)  }  // 如果没有提供数据缓冲去,则调配一段长期缓冲区  if buf == nil {      size := 32 * 1024      // LimitedReader 是io中实现的一个有读取长度限度的构造体,所以如果Read中实现了该构造体,则应用其定义的长度      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 || nr < nw {              nw = 0              if ew == nil {                  ew = errInvalidWrite              }          }          written += int64(nw)          if ew != nil {              err = ew              break          }          // 如果写入的数据无奈全副写,则返回 ErrShortWrite 谬误          if nr != nw {              err = ErrShortWrite              break          }      }      if er != nil {          if er != EOF {              err = er          }          break      }  }  // 返回 Copy 的数据长度  return written, err}