是我们经常使用io
处理数据的输入和输出,例如文件的读取和写入,网络的请求和响应,输出到命令行,从命令行读取输入等。
Go 中使用最多的接口是error
, 其次就是io.Reader
和 io.Writer
。
p
是一个字节切片,将数据放到p
中,返回读取的字节个数n
和过程中发生的错误err
我们来实现一个io.Reader
, 创建一个MyReader
结构体:
创建一个New这个结构体的方法:
实现Read
方法:
你可以使用内置的copy
函数把一个切片复制到另一个切片,返回复制的个数。既上述代码等价于:
直接调用io.Copy
它接收一个io.Writer
和一个io.Reader
, 把io.Reader
的数据复制到io.Writer
。来验证一下
运行
输出
完整代码:
上述的MyReader
就是标准库strings.Reader
的实现。
一个Write
方法,它从p
切片中拿出数据,返回拿出的byte
的个数和过程中的错误。
我们知道os.Stdout
是标准输出,即打印到命令行,同时实现了io.Writer
接口。我们来实现一个io.Writer
, 将字母变大写再打印到命令行:
创建MyWriter
结构体
创建New方法:
实现Write
方法,在这里将字母变大写。
我们把上一节代码中的os.Stdout
替换成MyWriter
试验一下:
运行
输出
成功,完整代码:
既然都实现到这了,就再实现一个简单的io.Copy
吧。它将数据从io.Reader
复制到io.Writer
。(完整的实现还得看标准库)
将io.Copy
替换成MyCopy
运行
输出
成功,
完整代码
运行,可以看到生成了hello.md
文件,内容为
注意事项,file
不是线程安全的,并发访问时需要加锁控制,例如:
我们来读取刚刚创建的hello.md
文件
输出
如果一个文件很大,一次性读取可能会把内存挤爆,我们需要分快读取:
输出
- 介绍了两个经典的接口
io.Reader
和io.Writer
- 如何创建文件,读取文件,写入文件。