Golang 中的 IO 包详解:常用的可导出函数详解

开发 后端
从 Reader 中读取数据并写入到 Writer 中,直到无法再从 Reader 中读取到任何数据(EOF)或发生错误,返回被复制的字节数和任何发生的错误信息。

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\n", 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\n", 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\n", 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\n", 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\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)个字节到 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)
	}
}
责任编辑:姜华 来源: 今日头条
相关推荐

2023-11-27 15:02:37

BytesGolang

2023-10-18 08:22:38

BufioGolang

2023-08-03 08:48:07

Golang接口

2023-08-02 09:07:27

Golangio 包

2023-08-28 17:16:51

Golangio 包

2023-08-08 14:51:29

2023-08-07 09:18:32

Golang偏移量接口

2023-10-31 09:10:39

2024-01-18 09:07:04

Errors函数Golang

2023-09-05 08:22:44

Golangstrings 包

2023-10-10 08:57:44

Golangbufio

2023-11-03 08:53:15

StrconvGolang

2023-10-07 09:08:32

Golangbufio

2023-09-06 09:10:04

Golang字符串

2023-09-07 07:35:54

GolangBufio

2023-11-07 09:02:07

Golangbytes

2023-09-04 08:17:37

Golangstrings 包

2023-11-29 07:47:29

Golang函数

2023-05-12 09:40:53

ContextGolang

2023-05-15 08:50:58

ContextGolang
点赞
收藏

51CTO技术栈公众号