Go 语言中,为了方便开发者使用,将IO操作封装在了如下几个包中
- io 为IO 原语 (IO primitives) 提供基本的接口 os File Reader Writer
- io/ioutil 封装一些实用的 I/O 函数
- fmt 实现格式化I/O,类似 C 语言中的 printf 和 scanf format fmt
- bufio 实现带缓冲I/O
基本的 IO 接口
在io 包中最重要的是两人接口: Reader 和 Writer 接口。下面所提到的各种IO包,都跟这两个接口有关,也就是说,只要实现了这两个接口,它就有了IO的功能 Reader接口
type Reader interface {
Read(p []byte) (n int, err error)
}
Writer接口
Write(p []byte) (n int, err error)
}
相关实现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.Reader/Writer 分别实现了 io.Reader 和 io.Writer
- crypto/cipher.StreamReader/StreamWriter 分别实现了 io.Reader 和 io.Writer
- crypto/tls.Conn 同时实现了 io.Reader 和 io.Writer
- encoding/csv.Reader/Writer 分别实现了 io.Reader 和 io.Writer
实例
以常用的strings.Reader为例实现一个copy到标准输出中
package main
import (
"io"
"log"
"os"
"strings"
)
func main() {
r := strings.NewReader("some io.Reader stream to be read\n")
if _, err := io.Copy(os.Stdout, r); err != nil {
log.Fatal(err)
}
}
输出如下
some io.Reader stream to be read
我们还可以通过借助开辟一片缓冲区来提高copy的效率,将reader先缓存到缓冲区,再拷贝到writer中,代码如下:
package main
import (
"io"
"log"
"os"
"strings"
)
func main() {
r1 := strings.NewReader("first reader\n")
r2 := strings.NewReader("second reader\n")
buf := make([]byte, 8)
// buf is used here...
if _, err := io.CopyBuffer(os.Stdout, r1, buf); err != nil {
log.Fatal(err)
}
// ... reused here also. No need to allocate an extra buffer.
if _, err := io.CopyBuffer(os.Stdout, r2, buf); err != nil {
log.Fatal(err)
}
}
输出如下:
first reader
second reader