io:基本的I/O接口
Reader接口
定义:
1 2 3type Reader interface{ Read(p []byte)(n int,err error) }Read方法将len(p)个字节读取到p中,返回值是读取的字节数和任何遇到的错误,这个错误可能是读取中遇到的意外或者EOF(end-of-file)。当
Read方法返回错误时,不代表没有读取到任何数据。调用者应该处理返回的任何数据,之后才处理可能的错误。即使
Read函数返回的的字节数小于p的长度,函数也会返回完整的p;如果读取的数据不到p的最大长度,Read方法会返回当前读取到的可用数据,不会继续等待读取。因为所有实现了
Read方法的类型都相当于实现了io.Reader接口,也就是说,在所有需要io.Reader的地方,可以传递实现了Read()方法的类型的实例。
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17func ReadFrom(reader io.Reader,num int)([]byte,error){ p := make([]byte,num) //创建长度为num的byte数组 n, err := reader.Read(p) //将reader中的数据读到p里面 if n > 0{ return p[:n],nil } return p ,err } // 从标准输入读取 data, err = ReadFrom(os.Stdin, 11) // 从普通文件读取,其中 file 是 os.File 的实例 data, err = ReadFrom(file, 9) // 从字符串读取 data, err = ReadFrom(strings.NewReader("from string"), 12)Writer接口定义:
1 2 3type Write interface{ Write(p []byte)(n ,int,err error) }所有实现了
Write方法的类型都实现了io.Write接口。Write方法将len(p)个字节写入基本数据流(也就是传递数据的io实例,例如os.Stdout、http.ResponseWriter),返回写入的字节数以及遇到的任何错误,不同的是,Write返回的字节数小于p的长度时,必须返回一个非nil的错误。
举例实现了io.Reader接口或io.Writer接口的标准库类型
- 一个能查看接口所有的实现类型的官网镜像:http://docs.studygolang.com
- 举例一些标准库类型
os.File同时实现了io.Reader和io.Writer接口strings.Readerbufio.Reader/Writerbytes.Buffer同时实现了io.Reader和io.Writerbytes.Readercompress/gzip.Reader/Writercrypto/cipher.StreamReader/StreamWritercrypto/tls.Conn同时实现了io.Reader和io.Writerencoding/csv.Reader/Writermime/multipart.Part实现了io.Readernet/conn分别实现了io.Reader和io.Writer(Conn接口定义了Read/Write)
ReaderAt和WriterAt接口
定义:
1 2 3 4 5 6type ReaderAt interface{ ReadAt(p []byte, off int64) (n int, err error) } type WriterAt interface { WriteAt(p []byte, off int64) (n int, err error) }ReadAt()和WriteAt()方法多了一个参数off int64,这个参数表示偏移量。实现的功能是从该制定的偏移量处读取/写入。ReadAt()方法比Read()方法严格一些,当返回的字节数小于p的长度时,必须要返回一个非nil的错误,通知调用方。Example:
1 2 3 4 5 6 7reader := strings.NewReader("Go标准库") p := make([]byte,9) n, err := reader.ReadAt(p,2) if err != nil{ panic(err) } fmt.Printf("%s,%d\n",p,n)输出:
1标准库,9注意:需要知道的是,如果上面代码中改成
p := make([]byte,10)将会触发panic,输出panic: EOF,这就可以看出ReadAt比Read严格的错误机制了。WriteAt方法基本一致,但是在写入的时候,会将从offset处开始到写入内容长度相同的这一段内容覆盖掉,举例:1 2 3// file是一个.txt文件,里面的内容是“Golang中文社区——这里是多余的” n,err := file.WriteAt([]byte("Go语言中文网"),24) //最终file中的内容变成了“Golang中文社区——Go语言中文网”,也就是从offset=24处写入的内容,将之前的内容覆盖掉了ReaderFrom和WriterTo接口定义:
1 2 3type ReadFrom interface{ ReadFrom(r Reader)(n int64,err error) }ReadFrom方法从一个reader中读取数据,读取到文件末尾(EOF)或者发生错误是进行返回,返回读取的字节数,还有发生的错误,或者io.EOF。