type Reader interface {
Read(p []byte) (n int, err error)
}
Read 将
len(p)
个字节读取到 p 中。它返回读取的字节数n(0 <= n <= len§)以及任何遇到的错误。
即使 Read 返回的 n < len§,它也会在调用过程中占用 len§ 个字节作为暂存空间。
若可读取的数据不到 len§ 个字节,Read 会返回可用数据,而不是等待更多数据。
当 Read 在成功读取 n > 0 个字节后遇到一个错误或 EOF (end-of-file),它会返回读取的字节数。它可能会同时在本次的调用中返回一个non-nil错误,或在下一次的调用中返回这个错误(且 n 为 0)。
一般情况下, Reader会返回一个非0字节数n, 若 n = len§ 个字节从输入源的结尾处由 Read 返回,Read可能返回 err = = EOF 或者 err == nil。并且之后的 Read() 都应该返回(n:0, err:EOF)
。
调用者在考虑错误之前应当首先处理返回的数据。这样做可以正确地处理在读取一些字节后产生的 I/O 错误,同时允许EOF的出现。
// ReadFrom以一个实现了Reader接口作为参数,也就是说它可以从任何地方读取数据, num表示读取几个字节
func ReadFrom(reader io.Reader, num int) ([]byte, error) {
p :=make([]byte,num) //num用来定义p的大小
n, err := reader.Read(p)
if n > 0 {
return p[:n], nil
}
return p, err
}
type Writer interface {
Writer(p []byte) (n int, err error)
}
Write 将 len§ 个字节从 p 中写入到基本数据流中。它返回从 p 中被写入的字节数 n(0 <= n <= len§)以及任何遇到的引起写入提前停止的错误。
若 Write 返回的 n < len§,它就必须返回一个 非nil 的错误。
//os.File同时实现了io.Writer/Reader
// 标准输入输出是他的实例
Stdin = NewFile(uintptr(syscall.Stdin),"/dev/stdin")
Stdout = NewFile(uintptr(syscall.Stdout),"/dev/stdout")
Stderr = NewFile(uintptr(syscall.Stderr),"/dev/stderr")
type ReaderAt interface {
// 从基本输入源的偏移量 off 处开始,将 len(p) 个字节读取到 p 中
ReadAt(p []byte, off int64) (n int, err error)
}
返回读取的字节数 n(0 <= n <= len§)以及任何遇到的错误。
当返回的 n < len§ 时,它就会返回一个 非nil 的错误来解释 为什么没有返回更多的字节。
它也会在调用过程中使用 p 的全部作为暂存空间。若可读取的数据不到 len§ 字节,ReadAt 就会阻塞,直到所有数据都可用或一个错误发生。
若 n = len§ 个字节从输入源的结尾处由 ReadAt 返回,Read可能返回 err = = EOF 或者 err == nil
若 ReadAt 携带一个偏移量从输入源读取**,ReadAt 应当既不影响偏移量也不被它所影响。**
type WriterAt interface {
// 从 p 中将 len(p) 个字节写入到偏移量 off 处的基本数据流中
WriteAt(p []byte, off int64) (n int, err error)
}
返回从 p 中被写入的字节数 n(0 <= n <= len§)以及任何遇到的引起写入提前停止的错误。
若 WriteAt 返回的 n < len§,它就必须返回一个 非nil 的错误。
若 WriteAt 携带一个偏移量写入到目标中,WriteAt 应当既不影响偏移量也不被它所影响。
type ReaderFrom interface {
//从 r 中读取数据,直到 EOF 或发生错误
ReadFrom(r Reader) (n int64, err error)
}
ReadFrom 方法不会返回 err == EOF。
type WriterTo interface {
// 将数据写入 w 中,直到没有数据可写或发生错误
WriteTo(w Writer) (n int64, err error)
}
type Seeker interface {
Seek(offset int64, whence int) (ret int64, err error)
}
Seek 设置下一次 Read 或 Write 的偏移量为 offset,它的解释取决于 whence: 0 表示相对于文件的起始处,1 表示相对于当前的偏移,而 2 表示相对于其结尾处。 Seek 返回新的偏移量和一个错误,如果有的话。
Seek 方法是用于设置偏移量的,这样可以从某个特定位置开始操作数据流。
const (
SeekStart = 0 // seek relative to the origin of the file
SeekCurrent = 1 // seek relative to the current offset
SeekEnd = 2 // seek relative to the end
)
type Closer interface {
Close() error
}
type ByteReader interface {
ReadByte() (c byte, err error)
}
type ByteWriter interface {
WriteByte(c byte) error
}
bufio.Reader/Writer 分别实现了io.ByteReader 和 io.ByteWriter
bytes.Buffer 同时实现了 io.ByteReader 和 io.ByteWriter
bytes.Reader 实现了 io.ByteReader
strings.Reader 实现了 io.ByteReader
type ByteScanner interface {
ByteReader //内嵌
UnreadByte() error //将上一次ReadByte的字节还原
//UnreadByte 调用之前必须调用了 ReadByte,且不能连续调用 UnreadByte
}
这些接口是上面介绍的接口的两个或三个组合而成的新接口。例如 ReadWriter 接口:
type ReadWriter interface {
Reader
Writer
}
SectionReader 是一个 struct(没有任何导出的字段),实现了 Read, Seek 和 ReadAt,同时,内嵌了 ReaderAt 接口
//该类型读取数据流中部分数据
type SectionReader struct {
r ReaderAt // 该类型最终的 Read/ReadAt 最终都是通过 r 的 ReadAt 实现
base int64 // NewSectionReader 会将 base 设置为 off
off int64 // 从 r 中的 off 偏移处开始读取数据
limit int64 // limit - off = SectionReader 流的长度
}
//从 r 中的偏移量 off 处读取 n 个字节后以 EOF 停止。
func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader
// 方便重复操作某一段 (section) 数据流;或者同时需要 ReadAt 和 Seek 的功能。
type LimitedReader struct {
R Reader // underlying reader,最终的读取操作通过 R.Read 完成
N int64 //最多只能返回 N 字节数据
}
从 R 读取但将返回的数据量限制为 N 字节。每调用一次 Read 都将更新 N 来反应新的剩余数量。
PipeReader(一个没有任何导出字段的 struct)是管道的读取端。它实现了 io.Reader 和 io.Closer 接口。结构定义如下:
type PipeReader struct {
p *pipe
}
从管道中读取数据。该方法会堵塞,直到管道写入端开始写入数据或写入端被关闭。如果写入端关闭时带有 error(即调用 CloseWithError 关闭),该Read返回的 err 就是写入端传递的error;否则 err 为 EOF。
PipeWriter(一个没有任何导出字段的 struct)是管道的写入端。它实现了 io.Writer 和 io.Closer 接口。结构定义如下:
type PipeWriter struct {
p *pipe
}
写数据到管道中。该方法会堵塞,直到管道读取端读完所有数据或读取端被关闭。如果读取端关闭时带有 error(即调用 CloseWithError 关闭),该Write返回的 err 就是读取端传递的error;否则 err 为 ErrClosedPipe。
// io.Pipe() 用于创建一个同步的内存管道 (synchronous in-memory pipe)
func Pipe() (*PipeReader, *PipeWriter)
它将 io.Reader 连接到 io.Writer。一端的读取匹配另一端的写入,直接在这两端之间复制数据;
对于管道的 close 方法(非 CloseWithError 时),err 会被置为 EOF。
func Copy(dst Writer, src Reader) (written int64, err error)
// 将 r 读取到 buf 中,直到读了最少 min 个字节为止
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
// 精确地从 r 中将 len(buf) 个字节读取到 buf 中
func ReadFull(r Reader, buf []byte) (n int, err error)
// s的内容写入w中,当w实现了 WriteString 方法时,会直接调用该方法,否则执行 w.Write([]byte(s))
func WriteString(w Writer, s string) (n int, err error)
func MultiReader(readers ...Reader) Reader //在所有的 Reader 内容都被读完后,Reader 会返回 EOF。
func MultiWriter(writers ...Writer) Writer
type multiReader struct {
readers []Reader
}
type multiWriter struct {
writers []Writer
}
func TeeReader(r Reader, w Writer) Reader