Golang 中的 IO 包詳解:常用的可導(dǎo)出函數(shù)詳解
io.Copy
func Copy(dst Writer, src Reader) (written int64, err error)
用于在 io.Reader 或 io.Writer 之間復(fù)制數(shù)據(jù),接受兩個(gè)參數(shù),一個(gè) Writer 和一個(gè) Reader。從 Reader 中讀取數(shù)據(jù)并寫入到 Writer 中,直到無(wú)法再?gòu)?Reader 中讀取到任何數(shù)據(jù)(EOF)或發(fā)生錯(cuò)誤,返回被復(fù)制的字節(jié)數(shù)和任何發(fā)生的錯(cuò)誤信息。簡(jiǎn)單的使用示例如下:
package main
import (
"fmt"
"io"
"os"
)
func main() {
src, err := os.Open("src.txt")
if err != nil {
panic(err)
}
defer src.Close()
dst, err := os.Create("dst.txt")
if err != nil {
panic(err)
}
defer dst.Close()
written, err := io.Copy(dst, src)
if err != nil {
panic(err)
}
fmt.Printf("Copied %d bytes\n", written)
}
io.CopyBuffer
func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
用于在 io.Reader 和 io.Writer 之間緩沖復(fù)制數(shù)據(jù),與 io.Copy 函數(shù)不同的是,使用 io.CopyBuffer 可以手動(dòng)控制緩沖區(qū)的大小。如果 buf 為 nil,則分配一個(gè);如果長(zhǎng)度為零,則會(huì)觸發(fā) panic。io.CopyBuffer 避免了 io.Copy 可能出現(xiàn)的大內(nèi)存使用問(wèn)題,因?yàn)榭梢允褂镁哂泄潭ù笮〉木彌_區(qū),所以可以更好地控制內(nèi)存使用、提高性能。簡(jiǎn)單使用示例如下:
package main
import (
"fmt"
"io"
"os"
)
func main() {
src, err := os.Open("src.txt")
if err != nil {
panic(err)
}
defer src.Close()
dst, err := os.Create("dst.txt")
if err != nil {
panic(err)
}
defer dst.Close()
buf := make([]byte, 4)
written, err := io.CopyBuffer(dst, src, buf)
if err != nil {
panic(err)
}
fmt.Printf("Copied %d bytes\n", written)
}
io.CopyN
func CopyN(dst Writer, src Reader, n int64) (written int64, err error)
用于從 io.Reader 中讀取指定數(shù)量的字節(jié)數(shù)并寫入 io.Writer 中。與 io.Copy 函數(shù)不同的是,會(huì)從源 io.Reader 中讀取 n 個(gè)字節(jié)并寫入到目標(biāo) io.Writer 中,從源讀入了指定數(shù)量的字節(jié)數(shù)據(jù)后就會(huì)停止。簡(jiǎn)單使用示例如下:
package main
import (
"fmt"
"io"
"os"
)
func main() {
src, err := os.Open("file.txt")
if err != nil {
panic(err)
}
defer src.Close()
dst, err := os.Create("dst.txt")
if err != nil {
panic(err)
}
defer dst.Close()
written, _ := io.CopyN(dst, src, 5)
fmt.Printf("Copied %d bytes\n", written)
}
io.LimitReader
func LimitReader(r Reader, n int64) Reader
從 io.Reader 中讀取數(shù)據(jù),最多返回 n 個(gè)字節(jié)。如果讀取數(shù)據(jù)時(shí)提前達(dá)到了這個(gè)限制,io.Reader 就會(huì)返回 io.EOF 錯(cuò)誤(表示已經(jīng)讀取到了流的末尾)。簡(jiǎn)單使用示例如下:
package main
import (
"fmt"
"io"
"strings"
)
func main() {
data := "Hello, World!"
reader := strings.NewReader(data)
limit := int64(5)
limitedReader := io.LimitReader(reader, limit)
buf := make([]byte, limit)
limitedReader.Read(buf)
fmt.Printf("%s\n", buf) // 輸出: Hello
}
io.ReadAll
func ReadAll(r Reader) ([]byte, error)
用于讀取指定 io.Reader 中所有數(shù)據(jù),不限制讀取數(shù)據(jù)的大小。簡(jiǎn)單使用示例如下:
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("路多辛的博客,分享后端領(lǐng)域知識(shí)與經(jīng)驗(yàn)")
b, err := io.ReadAll(r)
if err != nil {
panic(err)
}
fmt.Println(string(b))
}
io.ReadAtLeast
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
用于從 io.Reader 中讀取至少指定數(shù)量字節(jié)的數(shù)據(jù),會(huì)嘗試從 io.Reader 中讀取至少 min 個(gè)字節(jié),如果數(shù)據(jù)不足,會(huì)返回一個(gè)無(wú)法讀取請(qǐng)求的字節(jié)數(shù)錯(cuò)誤。簡(jiǎn)單使用示例如下:
package main
import (
"fmt"
"io"
"log"
"strings"
)
func main() {
r := strings.NewReader("路多辛的博客,分享后端領(lǐng)域知識(shí)與經(jīng)驗(yàn)")
buf := make([]byte, 18)
if _, err := io.ReadAtLeast(r, buf, 6); err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", buf)
shortBuf := make([]byte, 3)
if _, err := io.ReadAtLeast(r, shortBuf, 4); err != nil {
fmt.Println("error:", err)
}
longBuf := make([]byte, 64)
if _, err := io.ReadAtLeast(r, longBuf, 64); err != nil {
fmt.Println("error:", err)
}
}
io.ReadFull
func ReadFull(r Reader, buf []byte) (n int, err error)
用于從 io.Reader 中讀取 len(buf)個(gè)字節(jié)到 buf 中。如果數(shù)據(jù)不足,會(huì)返回一個(gè)無(wú)法讀取請(qǐng)求的字節(jié)數(shù)的錯(cuò)誤。簡(jiǎn)單使用示例如下:
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("路多辛的博客,分享后端領(lǐng)域知識(shí)與經(jīng)驗(yàn)")
buf := make([]byte, 18)
if _, err := io.ReadFull(r, buf); err != nil {
panic(err)
}
fmt.Println(string(buf))
longBuf := make([]byte, 64)
if _, err := io.ReadFull(r, longBuf); err != nil {
panic(err)
}
}