Go语言IO操作 - 1 interface io.Reader
source link: http://www.pengrl.com/p/20120/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
interface io.Reader
定义
// go/src/io/io.go type Reader interface { Read(p []byte) (n int, err error) }
interface io.Reader
语义
从 Reader
中读取数据,存入传入参数 p
中,并通过返回值 n
返回本次读取的大小,以及 err
返回可能存在的错误。
对于一次调用:
可能发生阻塞;不保证读够(读满) len(p)
的数据
-
n
取值范围0 <= n <= len(p)
-
即使读取到的数据
n < len(p)
,也不保证p
内存块后半部分的原始数据保持不变,不被修改 -
只要有数据可读,即使可读数据
n < len(p)
,也会立即返回,而不是等待读够len(p)
大小的数据
注意,如果没有数据可读并且也没有错误发生,会阻塞当前协程,直到数据可读或发生错误。
(注意,这里说的阻塞指的是上层代码的表现,Go的IO线程协程调度模型不在本文讨论范围内)
正确处理返回值
可能同时出现 n > 0
并且 err != nil
的情况。
当读取到结尾EOF(end-of-file)时,可以有两种方式
-
首次调用返回
n > 0
并且err != nil
-
首次调用返回
n > 0
并且err == nil
第二次调用返回 n == 0
并且 err == EOF
第一种方式,即使 err != nil
,也有可能读取到了数据。
所以,不管是以上哪种方式,正确处理应该是每次调用结束后,先判断 n
,处理读取到的数据,再判断 err
,像这样:
n, err := r.Read(p) if n > 0 { // ... // 注意,此处并没有return等跳过下面判断err值的逻辑 } if err != nil { // ... }
n == 0
并且 err == nil
-
正常来说,不应该出现
n == 0
的情况,除非len(p) == 0
-
当
n == 0
并且err == nil
时,应被认为啥事也没发生(一次空调用),而不是EOF
其他
函数调用结束后,内部不会持有 p
的内存
interface io.Reader
举例:
// 1. 读取文件 // go/src/os/file.go func (f *File) Read(b []byte) (n int, err error) { // ... } // 2. 读取网络连接 // go/src/net/net.go type Conn interface { Read(p []byte) (n int, err error) // ... }
本文完,作者 yoko ,尊重劳动人民成果,转载请注明原文出处: https://pengrl.com/p/20120/
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK