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)文章
Golang調(diào)用FFmpeg實現(xiàn)視頻截圖,裁剪與水印添加功能
這篇文章主要為大家詳細介紹了Golang如何調(diào)用FFmpeg實現(xiàn)視頻截圖,裁剪與水印添加功能,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下2026-02-02

