Go标准库IO包基础接口Reader,Writer,Seeker和Closer
Reader接口type Reader interface { Read(p []byte) (n int, err error) }
Reader像是从一个瓶子倒水出来(到切片中),而实现了Reader接口的东西就是瓶子,可以从中倒数据出来
源码对照翻译Read 将 len(p)个字节读取到 p 中。它返回读取的字节数 n(0 <= n <= len(p))以及任何遇到的错误即使 Read 返回的 n < len(p),它也会在调用过程中使用 p的全部作为暂存空间若一些数据可用但不到 len(p) 个字节,Read 会返回可用的东西,而不是等待更多数据
(...后略)
【分析:这段说明主要对Read的实现做了一些约束和参考,了解即可】
实例演示:
一、在项目目录下创建一个a.txt文件,写入:hello,golang
二、执行下列代码package main import ( "fmt" "io" "os" ) func main() { //打开文件 f, err := os.Open("a.txt") if err != nil { fmt.Printf("err: %v ", err) return } //关闭文件 defer f.Close() // 实例化一个长度为4的[]byte buf := make([]byte, 4) for { // 内容读至buf n, err2 := f.Read(buf) if n == 0 || err2 == io.EOF { fmt.Println("文件读取完毕") break } fmt.Println(string(buf[:n])) } }
运行结果:
hell
o,go
lang
文件读取完毕Writer接口type Writer interface { Write(p []byte) (n int, err error) }Write 将 len(p) 个字节从 p 中写入到基本数据流中。它返回从 p 中被写入的字节数n(0 <= n <= len(p))以及任何遇到的引起写入提前停止的错误。若 Write 返回的n < len(p),它就必须返回一个非nil的错误。Write 不能修改此切片的数据,即便它是临时的。
实例演示:func main() { //bytes.Buffer实现Writer接口 buf := new(bytes.Buffer) //写入数据 buf.Write([]byte("hello golang")) //查看数据 log.Println(buf.String()) }
运行结果:
2023/02/27 09:09:19 hello golangSeeker接口type Seeker interface { Seek(offset int64, whence int) (int64, error) }
Seeker 用来移动数据的读写指针
Seek 设置下一次读写操作的指针位置,每次的读写操作都是从指针位置开始的
whence 的含义:如果 whence 为 0:表示从数据的开头开始移动指针,io.SeekStart 如果 whence 为 1:表示从数据的当前指针位置开始移动指针,io.SeekCurrent 如果 whence 为 2:表示从数据的尾部开始移动指针,io.SeekEnd
offset 是指针移动的偏移量
返回移动后的指针位置和移动过程中遇到的任何错误
Seeker图示如下:
实例演示:func main() { //实现Seeker和Reader接口 rd := strings.NewReader("hello golang") //调整指针 _, err := rd.Seek(1, io.SeekStart) if err == nil { //读一字节 b, err := rd.ReadByte() //打印"e"的ASCII log.Println(b, err) } }
运行结果:
2023/02/27 09:37:20 101 Closer接口type Closer interface { Close() error }
Closer关闭的接口, 带有Close() 方法,但是行为没有定义,所以可以特定行为来实现
在整个标准库内都没有对Closer的引用,只有实现,用法都是开启某某连接/流,在用完/报错后在进行Close的操作。总结
总结了Reader/Writer/Seeker/Closer四个接口的作用和示例,下篇继续介绍后面的接口