go語言中io操作中的 io.Reader 和 io.Writer的獲取方法
我們在對文件進行io操作的時候,經(jīng)??吹叫枰覀儌鬟f一個 io.Reader 或者 io.Writer 對象作為讀寫的入?yún)ⅲ?那么我們該如何或者這些個RW對象呢? 其實很簡單,你只需要查找一下哪些對象實現(xiàn)了 Read或者 Writer方法,那么你只需要創(chuàng)建一個實現(xiàn)了這2個方法之一的對象 , 那他就可以是一個 io.Reader 或者 io.Writer 。
當(dāng)然最常見的應(yīng)該就是我們的 os.File對象了, 另外還有 bufio.Reader, bytes.Buffer 等對象都可以作為io的RW入?yún)ⅰ?/p>
當(dāng)然你也可以自己定義一個對象,實現(xiàn) io.Reader 或者 io.Writer 接口中定義的方法,那么你的對象也可以作為一個RW入?yún)硎褂昧恕?nbsp; 這個也就是go語言中面向接口編程的完美體現(xiàn)。
go中Reader Writer接口定義
type Reader interface { Read(p []byte) (n int, err error) } type Writer interface { Write(p []byte) (n int, err error) }
os.File對象中的RW實現(xiàn)代碼
// Read reads up to len(b) bytes from the File and stores them in b. // It returns the number of bytes read and any error encountered. // At end of file, Read returns 0, io.EOF. func (f *File) Read(b []byte) (n int, err error) { if err := f.checkValid("read"); err != nil { return 0, err } n, e := f.read(b) return n, f.wrapErr("read", e) } // Write writes len(b) bytes from b to the File. // It returns the number of bytes written and an error, if any. // Write returns a non-nil error when n != len(b). func (f *File) Write(b []byte) (n int, err error) { if err := f.checkValid("write"); err != nil { return 0, err } n, e := f.write(b) if n < 0 { n = 0 } if n != len(b) { err = io.ErrShortWrite } epipecheck(f, e) if e != nil { err = f.wrapErr("write", e) } return n, err }
bufio.Reader中的RW實現(xiàn)代碼
// Read reads data into p. // It returns the number of bytes read into p. // The bytes are taken from at most one Read on the underlying Reader, // hence n may be less than len(p). // To read exactly len(p) bytes, use io.ReadFull(b, p). // If the underlying Reader can return a non-zero count with io.EOF, // then this Read method can do so as well; see the [io.Reader] docs. func (b *Reader) Read(p []byte) (n int, err error) { n = len(p) if n == 0 { if b.Buffered() > 0 { return 0, nil } return 0, b.readErr() } if b.r == b.w { if b.err != nil { return 0, b.readErr() } if len(p) >= len(b.buf) { // Large read, empty buffer. // Read directly into p to avoid copy. n, b.err = b.rd.Read(p) if n < 0 { panic(errNegativeRead) } if n > 0 { b.lastByte = int(p[n-1]) b.lastRuneSize = -1 } return n, b.readErr() } // One read. // Do not use b.fill, which will loop. b.r = 0 b.w = 0 n, b.err = b.rd.Read(b.buf) if n < 0 { panic(errNegativeRead) } if n == 0 { return 0, b.readErr() } b.w += n } // copy as much as we can // Note: if the slice panics here, it is probably because // the underlying reader returned a bad count. See issue 49795. n = copy(p, b.buf[b.r:b.w]) b.r += n b.lastByte = int(b.buf[b.r-1]) b.lastRuneSize = -1 return n, nil } // writeBuf writes the Reader's buffer to the writer. func (b *Reader) writeBuf(w io.Writer) (int64, error) { n, err := w.Write(b.buf[b.r:b.w]) if n < 0 { panic(errNegativeWrite) } b.r += n return int64(n), err }
bytes.Buffer中的RW實現(xiàn)代碼
// Read reads the next len(p) bytes from the buffer or until the buffer // is drained. The return value n is the number of bytes read. If the // buffer has no data to return, err is io.EOF (unless len(p) is zero); // otherwise it is nil. func (b *Buffer) Read(p []byte) (n int, err error) { b.lastRead = opInvalid if b.empty() { // Buffer is empty, reset to recover space. b.Reset() if len(p) == 0 { return 0, nil } return 0, io.EOF } n = copy(p, b.buf[b.off:]) b.off += n if n > 0 { b.lastRead = opRead } return n, nil } // Write appends the contents of p to the buffer, growing the buffer as // needed. The return value n is the length of p; err is always nil. If the // buffer becomes too large, Write will panic with ErrTooLarge. func (b *Buffer) Write(p []byte) (n int, err error) { b.lastRead = opInvalid m, ok := b.tryGrowByReslice(len(p)) if !ok { m = b.grow(len(p)) } return copy(b.buf[m:], p), nil }
注意這些方法一般是綁定在指針類型的對象上, 所以你在創(chuàng)建你需要的RW對象的時候需要使用&指針符號或者使用 new函數(shù)來創(chuàng)建對象, 如:w := &bytes.Buffer{} 等效于 w := new(bytes.Buffer)
到此這篇關(guān)于go語言中io操作中的 io.Reader 和 io.Writer的獲取方法的文章就介紹到這了,更多相關(guān)go io.Reader io.Writer內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go使用TimerController解決timer過多的問題
多路復(fù)用,實際上Go底層也是一種多路復(fù)用的思想去實現(xiàn)的timer,但是它是底層的timer,我們需要解決的問題就過多的timer問題!本文給大家介紹了Go使用TimerController解決timer過多的問題,需要的朋友可以參考下2024-12-12Golang中int,?int8,?int16,?int32,?int64和uint區(qū)別淺析
go語言中的int的大小是和操作系統(tǒng)位數(shù)相關(guān)的,如果是32位操作系統(tǒng),int類型的大小就是4字節(jié),如果是64位操作系統(tǒng),int類型的大小就是8個字節(jié),下面這篇文章主要給大家介紹了關(guān)于Golang中int,?int8,?int16,?int32,?int64和uint區(qū)別的相關(guān)資料,需要的朋友可以參考下2022-11-11Golang實現(xiàn)請求限流的幾種辦法(小結(jié))
這篇文章主要介紹了Golang實現(xiàn)請求限流的幾種辦法(小結(jié)),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10