Go中Writer和Reader接口的使用入門
引言
我們學習其他語言編程時,會學到一個 io 包,這個包可以以流的方式高效處理數(shù)據(jù),而不用考慮數(shù)據(jù)是什么,數(shù)據(jù)來自哪里,以及數(shù)據(jù)要發(fā)送到哪里的問題。
io 是一個 Golang 標準庫包,它為圍繞輸入和輸出的許多操作和用例定義了靈活的接口。
io 包參見:golang.org/pkg/io/
與 stdout 和 stdin 對應,Go 語言實現(xiàn)了 io.Writer 和 io.Reader 兩個接口。通過實現(xiàn)這兩個接口,其他接口都可以使用 io 包提供的所有功能,也可以用于其他包里接收著兩個接口的函數(shù)以及方法。
Go 還提供了名為 bufio 和 ioutil 的包,其中包含與使用這些接口相關的有用功能。
Writer 接口
io.Writer 接口是 Go 非常小的接口之一。它只有一種方法。寫入方法。 Go 標準庫中的許多包都使用 io.Writer 接口,它表示將字節(jié)切片寫入數(shù)據(jù)流的能力。更一般地,允許您將數(shù)據(jù)寫入實現(xiàn) io.Writer 接口的東西。io.Writer 接口的聲明如下:
type Writer interface {
Writer(p []byte) (n int, err error)
}這個接口聲明了唯一一個方法 Writer,這個方法接收一個 byte 切片,并返回一個寫入的字節(jié)數(shù) n 和 error 錯誤值。
這里會有兩個點需要注意:
- Writer 從 p 字節(jié)切片的數(shù)據(jù)流寫入 len(p) 字節(jié)的數(shù)據(jù)。這個方法返回從 p 里寫出的字節(jié)數(shù)(0 <= n <= len(p) ),以及任何可能導致寫入提起結束的錯誤。
- Writer 在返回 n < len(p) 的時候,必須返回某個 nil 值的 error。Writer 絕不能改寫切片里的數(shù)據(jù),也不能臨時修改。
現(xiàn)在來看一個例子,看在 Go 中將數(shù)據(jù)寫入文件時如何使用 io.Writer:
package main
import (
"fmt"
"os"
)
func main() {
f, err := os.OpenFile("hello.txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600)
if err != nil {
panic(err)
}
defer f.Close()
n, err := f.Write([]byte("Hello, My name is LeeLei!"))
if err != nil {
panic(err)
}
fmt.Printf("wrote %d bytes", n)
}運行結果:wrote 25 bytes, 同時我們可以查看 hello.txt 文件內容:

os.File 的 Read 確實是同一個 io.Writer 接口的實現(xiàn),用于將字節(jié)切片寫入底層文件的數(shù)據(jù)流。這是 os.File.Write 的定義:
func (f *File) Write(b []byte) (n int, err error)
Reader 接口
然后來看一下 Reader 接口的聲明:
type Reader interface {
Read(p []byte) (n int, err error)
}Reader 是一個帶有強抽象的小接口!那個抽象到底是什么? Read 方法的想法是它表示從某個源讀取數(shù)據(jù)字節(jié),以便我們可以在代碼中使用這些字節(jié)。該來源可能是文件、相機、網(wǎng)絡連接,或者只是一個普通的舊字符串。例如,如果我們從文件中讀取數(shù)據(jù),我們將使用的 io.Reader 是 *os.File。
io.Reader 接口聲明了一個方法 Read,這個方法同樣接受一個 byte 切片,返回兩個值。第一個值是讀入的字節(jié)數(shù),第二個值是 error 錯誤值。
p []byte是我們傳遞給 Read 方法的字節(jié)切片。 Reader 將從其數(shù)據(jù)源(如文件)讀取的數(shù)據(jù)復制到該字節(jié)片。- 返回的
n int告訴我們在這個 Read 調用中讀取了多少字節(jié)。 - 返回的
err error是讀取數(shù)據(jù)時可能發(fā)生的任何錯誤,例如到達文件末尾。
讓我們用一個文件來嘗試一下,看看我們是如何使用它的。復制此文本并將其保存到名為 hello.txt 的新目錄中的文件中:
Hello, My name is LeeLei!
現(xiàn)在,讓我們編寫一些 Go 代碼來使用 File 的 Read 方法讀取它。復制此代碼并將其保存到與 hello.txt 位于同一目錄中的文件 main.go 中:
package main
import (
"log"
"os"
)
func main() {
file, err := os.OpenFile("hello.txt", os.O_RDWR|os.O_CREATE|os.O_RDONLY, 0600)
if err != nil {
log.Fatalf("error opening hello.txt: %v", err)
}
defer file.Close()
// Make a byte slice that's big enough to store a few words of the message
// we're reading
bytesRead := make([]byte, 33)
// Now read some data, passing in our byte slice
n, err := file.Read(bytesRead)
if err != nil {
log.Fatalf("error reading from hello.txt: %v", err)
}
// Take a look at the bytes we copied into the byte slice
log.Printf("We read \"%s\" into bytesRead (%d bytes)",
string(bytesRead), n)
}運行該代碼:go run main.go,然后可以看到如下輸出:
$ go run main.go
2022/04/18 22:56:29 We read "Hello, My name is LeeLei!" into bytesRead (25 bytes)
那么當我們調用 os.File.Read 時,Go 會從文件中讀取數(shù)據(jù),并將其復制到 bytesRead 中,由于沒有發(fā)生錯誤,因此返回的錯誤為 nil。我們將 bytesRead 切片傳遞給 Read 函數(shù),就像我們將杯子傳遞給汽水噴泉一樣!
總結
本篇文章簡單介紹了 Go 語言 io 包中的兩個很實用的接口:Writer 和 Reader,分別給出了這兩個接口的聲明和解釋,然后以一個簡單的例子在代碼中使用這兩個小巧的接口,但是 Go 語言設計這兩個接口的用法遠遠不止這些,也需要我們不斷去探索其他功能,甚至學有余力去理解 Go 這樣的設計的原理。
到此這篇關于Go中Writer和Reader接口的使用入門的文章就介紹到這了,更多相關Go Writer和Reader接口內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
使用dep 配置golang 開發(fā)環(huán)境的操作方法
下面小編就為大家?guī)硪黄褂胐ep 配置golang 開發(fā)環(huán)境的操作方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09
golang實現(xiàn)http server提供文件下載功能
這篇文章主要介紹了golang實現(xiàn)http server提供文件下載功能,本文給大家簡單介紹了Golang的相關知識,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2020-02-02

