您现在的位置是:首页 >技术杂谈 >Golang 中的 io 包详解(六):常用的可导出函数详解网站首页技术杂谈

Golang 中的 io 包详解(六):常用的可导出函数详解

路多辛 2024-10-26 12:01:03
简介Golang 中的 io 包详解(六):常用的可导出函数详解

io.Copy

func Copy(dst Writer, src Reader) (written int64, err error)

用于在  io.Reader 或 io.Writer 之间复制数据,接受两个参数,一个 Writer 和一个 Reader。从 Reader 中读取数据并写入到 Writer 中,直到无法再从 Reader 中读取到任何数据(EOF)或发生错误,返回被复制的字节数和任何发生的错误信息。简单的使用示例如下:

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
", written)
}

io.CopyBuffer

func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)

用于在 io.Reader 和 io.Writer 之间缓冲复制数据,与 io.Copy 函数不同的是,使用 io.CopyBuffer 可以手动控制缓冲区的大小。如果 buf 为 nil,则分配一个;如果长度为零,则会触发 panic。io.CopyBuffer 避免了 io.Copy 可能出现的大内存使用问题,因为可以使用具有固定大小的缓冲区,所以可以更好地控制内存使用、提高性能。简单使用示例如下:

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
", written)
}

io.CopyN

func CopyN(dst Writer, src Reader, n int64) (written int64, err error)

用于从 io.Reader 中读取指定数量的字节数并写入 io.Writer 中。与 io.Copy 函数不同的是,会从源 io.Reader 中读取 n 个字节并写入到目标 io.Writer 中,从源读入了指定数量的字节数据后就会停止。简单使用示例如下:

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
", written)
}

io.LimitReader

func LimitReader(r Reader, n int64) Reader

从  io.Reader 中读取数据,最多返回 n 个字节。如果读取数据时提前达到了这个限制,io.Reader 就会返回 io.EOF 错误(表示已经读取到了流的末尾)。简单使用示例如下:

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
", buf) // 输出: Hello
}

io.ReadAll

func ReadAll(r Reader) ([]byte, error)

用于读取指定 io.Reader 中所有数据,不限制读取数据的大小。简单使用示例如下:

package main

import (
	"fmt"
	"io"
	"strings"
)

func main() {
	r := strings.NewReader("路多辛的博客,分享后端领域知识与经验")
	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 中读取至少指定数量字节的数据,会尝试从 io.Reader 中读取至少 min 个字节,如果数据不足,会返回一个无法读取请求的字节数错误。简单使用示例如下:

package main

import (
	"fmt"
	"io"
	"log"
	"strings"
)

func main() {
	r := strings.NewReader("路多辛的博客,分享后端领域知识与经验")
	buf := make([]byte, 18)
	if _, err := io.ReadAtLeast(r, buf, 6); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", 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)个字节到 buf 中。如果数据不足,会返回一个无法读取请求的字节数的错误。简单使用示例如下:

package main

import (
	"fmt"
	"io"
	"strings"
)

func main() {
	r := strings.NewReader("路多辛的博客,分享后端领域知识与经验")

	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)
	}
}

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。