概述
在使用Go语言的过程中,无论是实现web应用程序,还是控制台输入输出,又或者是网络操作,不可避免的会遇到IO操作,使用到io.Reader和io.Writer接口。
io.Reader
io.Reader
表示一个读取器,它将数据从某个资源读取到传输缓冲区。在缓冲区中,数据可以被流式传输和使用。
io.Reader接口定义如下:
1 2 3
| type Reader interface { Read(p []byte) (n int, err error) }
|
io.Reader
接口定义了Read(p []byte) (n int, err error)
方法,我们可以使用它从Reader中读取一批数据。在Reader中:
- 一次最多读取
len(p)
长度的数据
- 读取遭遇到error(io.EOF或者其它错误), 会返回已读取的数据的字节数和error
- 即使读取字节数< len(p),也不会更改p的大小
- 当输入流结束时,调用它可能返回
err == EOF
或者 err == nil
,并且n >=0
, 但是下一次调用肯定返回 n=0
, err=io.EOF
io.Writer
io.Writer
表示一个编写器,它从缓冲区读取数据,并将数据写入目标资源。
io.Writer接口定义如下:
1 2 3
| type Writer interface { Write(p []byte) (n int, err error) }
|
Write()
方法有两个返回值,一个是写入到目标资源的字节数,一个是发生错误时的错误。
接口继承关系
围绕着io.Reader io.Writer
接口的实现,主要有:
net.Conn, os.Stdin, os.File: 网络、标准输入输出、文件的流读取
strings.Reader: 把字符串抽象成Reader
bytes.Reader: 把[]byte
抽象成Reader
bytes.Buffer: 把[]byte
抽象成Reader和Writer
bufio.Reader/Writer: 抽象成带缓冲的流读取(比如按行读写)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
| func stringReader() { reader := strings.NewReader("hello world") b := make([]byte, 4)
for { n, err := reader.Read(b) if err != nil { if err == io.EOF { fmt.Println("finish read") break }
fmt.Println(err) os.Exit(1) } fmt.Println(n, string(b[:n])) } }
func bufferWriter() { providers := []string{ "hello", "world", "golang", "is great", }
var writer bytes.Buffer for _, s := range providers { n, err := writer.Write([]byte(s)) if err != nil { fmt.Println(err) os.Exit(1) }
if n != len(s) { fmt.Println("failed to write data") os.Exit(1) } }
fmt.Println(writer.String()) }
func fileWriter() { file, err := os.Create("./files.txt") if err != nil { fmt.Println(err) os.Exit(1) }
defer file.Close()
providers := []string{ "hello", "world", "golang", "is great", }
for _, p := range providers { c, err := file.Write([]byte(p)) if err != nil { fmt.Println(err) os.Exit(1) }
if c != len(p) { fmt.Println("failed to write data") os.Exit(1) } } }
func fileReader() { file, err := os.Open("./files.txt") if err != nil { fmt.Println(err) os.Exit(1) }
defer file.Close()
p := make([]byte, 4) for { n, err := file.Read(p) if err != nil { if err == io.EOF { break }
fmt.Println(err) }
fmt.Println(string(p[:n])) } }
func bufReader() { file, err := os.Open("./files.txt") if err != nil { panic(err) }
defer file.Close()
p := make([]byte, 4) reader := bufio.NewReader(file) for { n, err := reader.Read(p) if err != nil { if err == io.EOF { break } panic(err) }
fmt.Println(string(p[:n])) } }
func ioutilReader() { bytes, err := ioutil.ReadFile("./files.txt") if err != nil { panic(err) }
fmt.Println(string(bytes)) }
|
参考文档