Golang入门指南之标准库io包|青训营

70 阅读1分钟

Go 语言中,为了方便开发者使用,将IO操作封装在了如下几个包中

  1. io 为IO 原语 (IO primitives) 提供基本的接口 os File Reader Writer
  2. io/ioutil 封装一些实用的 I/O 函数
  3. fmt 实现格式化I/O,类似 C 语言中的 printf 和 scanf format fmt
  4. 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接口,例如:

  1. os.File 同时实现了 io.Reader 和 io.Writer
  2. strings.Reader 实现了 io.Reader
  3. bufio.Reader/Writer 分别实现了 io.Reader 和 io.Writer
  4. bytes.Buffer 同时实现了 io.Reader 和 io.Writer
  5. bytes.Reader 实现了 io.Reader
  6. compress/gzip.Reader/Writer 分别实现了 io.Reader 和 io.Writer
  7. crypto/cipher.StreamReader/StreamWriter 分别实现了 io.Reader 和 io.Writer
  8. crypto/tls.Conn 同时实现了 io.Reader 和 io.Writer
  9. 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