在本章的所有的io接口时,有一个特点,在读取或写入的n=len(p)时,返回的接口err=nil或者err=EOF;当n<len(p)时,需要返回err解释原因。
1. Reader接口
在官方io包中定义了如下接口,只要实现了Read方法,就是将其传递为io.Reader类型的参数
1 | type Reader interface { |
2. Writer接口
在官方的io包中定义里如下接口,只要实现了Write方法,也就是实现了Writer接口
1 | type Writer interface{ |
3. 实现Reader和Writer接口的类型
- os.File同时实现了io.Reader和io.Writer接口
- strings.Reader实现了io.Reader接口
- bufio.Reader/Writer分别实现了io.Reader和io.Writer接口
- bytes.Buffer同时实现了io.Reader和io.Writer接口
- bytes.Reader实现了io.Reader接口
- compress/gzip.StreamReader/StreamWriter分别实现了io.Reader和io.Writer接口
- encoding/csv.Reader/Writer分别实现了io.Reader和io.Writer接口
- net/conn分别实现了io.Reader和io.Writer接口(Conn接口定义了Read/Write)
4. ReaderAt接口
该接口是从源输入的偏移量off处读取len(p)个字节到p中。1
2
3type ReaderAt struct {
ReadAt(p []byte, off int64)(n int, err error)
}5. WriterAt接口
该接口是在源输出的偏移量off处写入len(p)个字节。1
2
3type WriterAt struct {
WriteAt(p []byte, off int64)(n int, err error)
}6. ReaderFrom接口
ReadFrom从r中读取数据,直到EOF或发生错误。使用示例1
2
3type ReaderFrom struct {
ReadFrom(r Reader)(n int64, err error)
}1
2
3
4
5
6
7
8
9file, err := os.Open("writerAt.txt")
if err != nil{
painc(err)
}
defer file.Close()
writer := bufio.NewWriter(os.Stdout)
writer.ReadFrom(file)
writer.Flush()7. WriterTo接口
emsp;WriteTo 将数据写入 w 中,直到没有数据可写或发生错误。1
2
3type WriterTo struct{
WriteTo(w Writer)(n int, err error)
}8. Seeker接口
Seek 设置下一次 Read 或 Write 的偏移量为 offset,它的解释取决于 whence: 0 表示相对于文件的起始处,1 表示相对于当前的偏移,而 2 表示相对于其结尾处。 Seek 返回新的偏移量和一个错误,如果有的话。1
2
3
4
5
6
7
8
9const(
SeekStart = 0
SeekCurrent = 1
SeekEnd = 2
)
type Seeker struct{
Seek(offset int64, whence int)(ret int64, err error)
}9. Closer接口
接口定义如下:1
2
3type Closer interface{
Close() error
}
10. ByteReader和ByteWriter接口
这个两个接口用于读/写一个字节
1 | type ByteReader interface{ |
在标准库中,有如下类型实现了 io.ByteReader 或 io.ByteWriter:
bufio.Reader/Writer 分别实现了io.ByteReader 和 io.ByteWriter
bytes.Buffer 同时实现了 io.ByteReader 和 io.ByteWriter
bytes.Reader 实现了 io.ByteReader
strings.Reader 实现了 io.ByteReader
11. ByteScanner、RuneReader和RuneScanner接口
UnreadByte 方法的意思是:将上一次 ReadByte 的字节还原,使得再次调用 ReadByte 返回的结果和上一次调用相同,也就是说,UnreadByte 是重置上一次的 ReadByte。注意,UnreadByte 调用之前必须调用了 ReadByte,且不能连续调用 UnreadByte。
1 | type ByteScanner interface { |
12. SectionReader接口
NewSectionReader 返回一个 SectionReader,它从 r 中的偏移量 off 处读取 n 个字节后以 EOF 停止。也就是说,SectionReader 只是内部(内嵌)ReaderAt 表示的数据流的一部分:从 off 开始后的 n 个字节。
这个类型的作用是:方便重复操作某一段 (section) 数据流;或者同时需要 ReadAt 和 Seek 的功能。
1 | type SectionReader struct { |
- LimitedReader接口
从 R 读取但将返回的数据量限制为 N 字节。每调用一次 Read 都将更新 N 来反应新的剩余数量。也就是说,最多只能返回 N 字节数据。使用示例1
2
3
4type LimitedReader struct {
R Reader //underlying reader,最终的读取通过R.Read完成
N int64 //max bytes remaining
}1
2
3
4
5
6
7
8
9
10
11content := "This is LimitReader Example"
reader := strings.NewReader(content)
limitReader := &io.LimitedReader{R:reader, N:8}
for limitReader.N > 0{
tmp := make([]byte, 2)
limitReader.Read(tmp)
fmt.Printf("%s", tmp)
}
//输出: This Is
//从结果看一看出最多只能读取N个字符
14. PipeReader和PipeWriter接口
关于 PipeReader.Read 方法的说明:从管道中读取数据。该方法会堵塞,直到管道写入端开始写入数据或写入端被关闭。如果写入端关闭时带有 error(即调用 CloseWithError 关闭),该Read返回的 err 就是写入端传递的error;否则 err 为 EOF。
关于 PipeWriter.Write 方法的说明:写数据到管道中。该方法会堵塞,直到管道读取端读完所有数据或读取端被关闭。如果读取端关闭时带有 error(即调用 CloseWithError 关闭),该Write返回的 err 就是读取端传递的error;否则 err 为 ErrClosedPipe。
1 | type PipeReader struct { |
使用示例如下
1 | func main() { |
15. Copy和CopyN函数
Copy 将 src 复制到 dst,直到在 src 上到达 EOF 或发生错误。它返回复制的字节数,如果有错误的话,还会返回在复制时遇到的第一个错误。成功的 Copy 返回 err == nil,而非 err == EOF。由于 Copy 被定义为从 src 读取直到 EOF 为止,因此它不会将来自 Read 的 EOF 当做错误来报告。
若 dst 实现了 ReaderFrom 接口,其复制操作可通过调用 dst.ReadFrom(src) 实现。此外,若 src 实现了 WriterTo 接口,其复制操作可通过调用 src.WriteTo(dst) 实现。
1 | func Copy(dst Writer, src Reader)(written int64, err error){} |
CopyN 将 n 个字节(或到一个error)从 src 复制到 dst。 它返回复制的字节数以及在复制时遇到的最早的错误。当且仅当err == nil时,written == n 。
若 dst 实现了 ReaderFrom 接口,复制操作也就会使用它来实现。
1 | func CopyN(dst Writer, src Reader, n int64)(written int64, err error){} |
16. ReadAtLeast和ReadFull函数
ReadAtLeast 将 r 读取到 buf 中,直到读了最少 min 个字节为止。它返回复制的字节数,如果读取的字节较少,还会返回一个错误。若没有读取到字节,错误就只是 EOF。如果一个EOF 发生在读取了少于min个字节之后,ReadAtLeast就会返回ErrUnexpectedEOF。若 min 大于 buf 的长度,ReadAtLeast 就会返回ErrShortBuffer。对于返回值,当且仅当 err == nil 时,才有 n >= min。
1 | func ReadAtLeast(r Reader, buf []byte, min int)(n int, err error){} |
ReadFull 精确地从 r 中将 len(buf) 个字节读取到 buf 中。它返回复制的字节数,如果读取的字节较少,还会返回一个错误。若没有读取到字节,错误就只是 EOF。如果一个 EOF 发生在读取了一些但不是所有的字节后,ReadFull 就会返回 ErrUnexpectedEOF。对于返回值,当且仅当 err == nil 时,才有 n == len(buf)。
1 | func ReadFull(r Reader, buf []byte)(n int, err error) |
17. WriteString函数
WriteString 将s的内容写入w中,当 w 实现了 WriteString 方法时,会直接调用该方法,否则执行 w.Write([]byte(s))。
1 | func WriteString(w writer, s string)(n int, err error) |
18. MultiReader和MultiWriter函数
1 | type multiReader struct { |
使用示例如下:
1 | readers := []io.Reader{ |
1 | file, err := os.Create("tmp.txt") |
参考文章:
《Go语言标准库》
- 本文标题:Golang基本输入输出(io包接口)
- 本文作者:lookupman
- 创建时间:2020-10-25 16:22:58
- 本文链接:https://lookupman.cn/2020/10/25/Golang基本输入输出(io包接口)/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!