[TOC] ## Reader 接口 ``` func ReadFrom(reader io.Reader, num int) ([]byte, error) { p := make([]byte, num) n, err := reader.Read(p) if n > 0 { return p[:n], nil } return p, err } // 从标准输入读取 data, err = ReadFrom(os.Stdin, 11) // 从普通文件读取,其中 file 是 os.File 的实例 data, err = ReadFrom(file, 9) // 从字符串读取 data, err = ReadFrom(strings.NewReader("from string"), 12) ``` demo2 ``` reader := strings.NewReader("hello word") buf := make([]byte, 2) for _, err := reader.Read(buf); err != io.EOF; _, err = reader.Read(buf) { if err != nil { panic(err) } fmt.Printf("%s\n", buf) ``` demo3 ``` reader := strings.NewReader("helo") //常规 p := make([]byte, 1) reader.Read(p) fmt.Println(string(p)) //h reader.Read(p) fmt.Println(string(p)) //e reader.Read(p) fmt.Println(string(p)) //l ``` ## Seeker 偏移量 ``` const ( SeekStart = 0 // 相对开始位置的偏移量 SeekCurrent = 1 // 相对当前位置的偏移量 SeekEnd = 2 // 相对结束位置的偏移量 ) ``` ``` reader := strings.NewReader("hello word") reader.Seek(6, io.SeekStart) //参数一偏移量, 参数二偏移类型 p := make([]byte, 2) reader.Read(p) fmt.Println(string(p)) //wo ``` ## Closer接口 文件 (os.File)、归档(压缩包)、数据库连接、Socket 等需要手动关闭的资源都实现了 Closer 接口。 最好先判断错误,在进行 `defer file.Close()` ``` file, err := os.Open("studygolang.txt") if err != nil { ... } defer file.Close() ``` ## PipeReader 与 PipeWriter ``` func main() { pipeReader, pipeWriter := io.Pipe() go PipeWrite(pipeWriter) go PipeRead(pipeReader) time.Sleep(30 * time.Second) } func PipeWrite(writer *io.PipeWriter){ data := []byte("Go语言中文网") for i := 0; i < 3; i++{ n, err := writer.Write(data) if err != nil{ fmt.Println(err) return } fmt.Printf("写入字节 %d\n",n) } writer.CloseWithError(errors.New("写入段已关闭")) } func PipeRead(reader *io.PipeReader){ buf := make([]byte, 128) for{ fmt.Println("接口端开始阻塞5秒钟...") time.Sleep(5 * time.Second) fmt.Println("接收端开始接受") n, err := reader.Read(buf) if err != nil{ fmt.Println(err) return } fmt.Printf("收到字节: %d\n buf内容: %s\n",n,buf) } } ``` ## Copy `io.Copy(os.Stdout, strings.NewReader("Go语言中文网")) ` ## CopyN `io.CopyN(os.Stdout, strings.NewReader("hello wored"), 3) ` ## WriteString byte以string 方式写入 支持 `StringWriter`接口即可,有 `file`,`reponseWrite` ``` file, _ := os.OpenFile("abc", os.O_RDWR, 0777) io.WriteString(file, "aaaaa22222") ``` ### MultiReader 和 MultiWriter 函数 ``` readers := []io.Reader{ bytes.NewBufferString("123"), strings.NewReader("abc"), } reader := io.MultiReader(readers...) p := make([]byte, 50) reader.Read(p) fmt.Println(string(p)) //abc ``` 说明 `MultiReader`只是把多个reader 作为切片连接,并不能一次获取所有的reader,只有当第一个获取完才可以获取第二个