圖片來源 https://medium.com/learning-the-go-programming-language/streaming-io-in-go-d93507931185golang
type Reader interface { Read(p []byte) (n int, err error) } type Writer interface { Write(p []byte) (n int, err error) }
package main import ( "io" "net/http" "os" "strings" ) type R struct { reader io.Reader } func NewReader(r io.Reader) *R { return &R{ reader: r, } } func (r *R) Read(p []byte) (n int, err error) { if _, err = r.reader.Read(p); err != nil { return } return len(p), nil } func main() { netR, err := http.Get("https://www.bilibili.com/") if err != nil { panic(err) } defer netR.Body.Close() fileR, err := os.Open("/tmp/data.txt") if err != nil { panic(err) } //讀內存 r1 := NewReader(strings.NewReader("")) b := make([]byte, 10*1024) if _, err := r1.Read(b); err != nil { panic(err) } //讀網絡 r2 := NewReader(netR.Body) if _, err := r2.Read(b); err != nil { panic(err) } //讀文件 r3 := NewReader(fileR) if _, err := r3.Read(b); err != nil { panic(err) } }
參考:https://medium.com/golangspec/introduction-to-bufio-package-in-golang-ad7d1877f762緩存
func buffer() { fmt.Println("IO") w := new(W) w.Write([]byte{'1'}) w.Write([]byte{'2'}) w.Write([]byte{'3'}) w.Write([]byte{'4'}) fmt.Println("Buffer IO") bw := bufio.NewWriterSize(w, 3) bw.Write([]byte{'1'}) bw.Write([]byte{'2'}) bw.Write([]byte{'3'}) bw.Write([]byte{'4'}) err := bw.Flush() if err != nil { panic(err) } } type W struct { } func (*W) Write(p []byte) (n int, err error) { fmt.Println("length is ", len(p)) fmt.Println(string(p)) return len(p), nil }
type ReaderFrom interface { ReadFrom(r Reader) (n int64, err error) }
func ReadFrom() { sr := strings.NewReader("read from strings reader") w := new(W) bw := bufio.NewWriterSize(w, 6) if _, err := bw.ReadFrom(sr); err != nil { panic(err) } if err := bw.Flush(); err != nil { panic(err) } }
s := strings.NewReader("abc|defg\nhij") r := bufio.NewReader(s) b, err := r.ReadSlice('|') if err != nil { panic(err) } fmt.Println(string(b)) b, err = r.ReadSlice('\n') if err != nil { panic(err) } fmt.Println(string(b))