package my_io type eofReader struct { } func (eofReader) Read([]byte) (int, error) { return 0,EOF } type multiReader struct { readers []Reader } func (mr *multiReader) Read(p []byte) (n int, err error) { for len(mr.readers)>0{ // 对展开嵌套multiReaders的优化(Issue 13558) // 如果readers只有一个元素且也是multiReader类型的,直接将元素的readers赋值给最外层的readers if len(mr.readers)==1{ if r,ok:=mr.readers[0].(*multiReader);ok{ mr.readers=r.readers continue } } // 每次从切片中读取第一个Reader的数据 n,err=mr.readers[0].Read(p) if err==EOF{ // 在改善展开嵌套的问题(Issue 18232)后用eofReader代替nil来避免nil报错 mr.readers[0]=eofReader{} // 将readers收缩以排除已经读取完的reader mr.readers=mr.readers[1:] } // 它们会被顺序读取。一旦所有的Reader都返回EOF,那么Read if n>0 || err!=EOF{ if err==EOF&&len(mr.readers)>0{ // 先不要返回EOF,因为readers中还保留有Reader err=nil } return } } // 所有Reader的数据都读取完了 return 0,EOF } // MultiReader返回一个Reader, 那是提供的readers的逻辑上的串联, // 它们会被顺序读取。一旦所有的输入都返回EOF,那么Read就会返回EOF。 // 如果readers的任何一个Reader返回一个非空,非EOF的错误,那么Read会返回那个错误 func MultiReader(readers ...Reader) Reader { r:=make([]Reader,len(readers)) copy(r,readers) return &multiReader{ r, } } type multiWriter struct { writers []Writer } 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 } } return len(p),err } // 利用编译器检查*multiWriter是否实现了StringWriter接口,以及显示规定*multiWriter一定要实现StringWriter接口 var _ StringWriter = (*multiWriter)(nil) func (t *multiWriter) WriteString(s string) (n int, err error) { var p []byte // 当需要的时候懒初始化 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 } } return len(s),nil } // MultiWriter创建一个writer,这个writer对每个提供的writer都进行重复的写操作 // // 写操作会写入到每个writer,但一次只写一个 // 如果列出的writer有一个返回了一个错误,那么所有的写操作都会停止并且返回这个错误,不会继续按照列表执行下去。 func MultiWriter(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} }
有疑问加站长微信联系(非本文作者)