前言
在Go中,输入和输出操作都是使用原语实现的,原语将数据模拟成可读的
或者可写的
字节流。
而Go的io包提供了io.Reader
(将数据从某个资源读取到传输缓冲区被流式传输和使用)和io.Writer
(从缓冲区读取数据,并写入目标资源)接口。
实现了
io.Reader
接口的唯一方法Read(p []byte)(n int, err error)
,它就是一个读取器。- n 读取到的字节数
err 发生错误的信息(注意:资源读取完毕返回io.EOF错误)
使用Reader
思路:
Reader
方法内部是循环被调用的,每次迭代都会从数据源取一块数据放入缓冲区p
,资源读取完毕返回io.EOF
错误为止。
我们通过strings.NewReader(string)
创建一个字符串读取器来迭代读取:package main import ( "fmt" "io" "os" "strings" ) func main() { //创建一个字符串读取器 reader := strings.NewReader("How are you today You were in a bad mood yesterday") //创建一个长度为3的切片 p := make([]byte, 3) //循环取数据 for { //读取到的字节数,err 发生错误的信息(注意:资源读取完毕返回io.EOF错误) n, err := reader.Read(p) if err != nil { if err == io.EOF { fmt.Println("The resource is read!") break } fmt.Println("Read err :", err.Error()) os.Exit(1) } fmt.Println(string(p[:n]), p[:n]) } }
输出打印的内容:
How [72 111 119]
ar [32 97 114]
e y [101 32 121]
ou [111 117 32]
tod [116 111 100]
ay [97 121 32]
You [89 111 117]
we [32 119 101]
re [114 101 32]
in [105 110 32]
a b [97 32 98]
ad [97 100 32]
moo [109 111 111]
d y [100 32 121]
est [101 115 116]
erd [101 114 100]
ay [97 121]The resource is read!
拓展例子(读取文件行数并且打印每一行内容和二进制流)
package main import ( "bufio" "fmt" "os" "time" ) func main() { if len(os.Args) < 2 { os.Exit(1) } filename := os.Args[1] file, err := os.Open(filename) defer file.Close() if err != nil { fmt.Println(err.Error()) os.Exit(1) } reader := bufio.NewReader(file) var line int fmt.Print("下面为你读取",filename,"每一行的内容:\n") for { lineContent, isPrefix, err := reader.ReadLine() if err != nil { break } if !isPrefix { line++ time.Sleep(time.Second*1) fmt.Println("第",line,"行的二进制数据流为:", lineContent,"内容是:",string(lineContent)) fmt.Print("\n") } } fmt.Println("名字为:",filename,"的文件一共有:", line,"行") }
Comment here is closed