io 包基本用法


io 包提供了 I/O 原语的基本接口,在 Go 语言中,几乎所有 I/O 相关的操作都实现了这些接口。

核心接口

Reader 和 Writer

package main

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

func main() {
	// Reader 接口示例
	reader := strings.NewReader("Hello, World!")

	// 读取数据
	buf := make([]byte, 5)
	n, err := reader.Read(buf)
	if err != nil {
		panic(err)
	}
	fmt.Printf("读取了 %d 字节: %s\n", n, buf[:n])

	// 继续读取
	n, err = reader.Read(buf)
	if err != nil {
		panic(err)
	}
	fmt.Printf("读取了 %d 字节: %s\n", n, buf[:n])

	// Writer 接口示例
	var buffer bytes.Buffer
	writer := &buffer

	n, err = writer.Write([]byte("Hello"))
	if err != nil {
		panic(err)
	}
	fmt.Printf("写入了 %d 字节\n", n)

	n, err = writer.Write([]byte(", World!"))
	if err != nil {
		panic(err)
	}
	fmt.Printf("总计写入: %s\n", buffer.String())
}

Copy 函数

package main

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

func main() {
	// io.Copy: 从 Reader 复制到 Writer
	src := strings.NewReader("这是要复制的数据")
	var dst bytes.Buffer

	n, err := io.Copy(&dst, src)
	if err != nil {
		panic(err)
	}
	fmt.Printf("复制了 %d 字节: %s\n", n, dst.String())

	// io.CopyN: 复制指定字节数
	src2 := strings.NewReader("Hello, World!")
	var dst2 bytes.Buffer

	n, err = io.CopyN(&dst2, src2, 5)
	if err != nil {
		panic(err)
	}
	fmt.Printf("复制了 %d 字节: %s\n", n, dst2.String())

	// io.CopyBuffer: 使用自定义缓冲区
	src3 := strings.NewReader("使用自定义缓冲区复制数据")
	var dst3 bytes.Buffer
	buf := make([]byte, 8)

	n, err = io.CopyBuffer(&dst3, src3, buf)
	if err != nil {
		panic(err)
	}
	fmt.Printf("复制了 %d 字节: %s\n", n, dst3.String())
}

ReadAll 和 ReadFull

package main

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

func main() {
	// io.ReadAll: 读取所有数据
	reader := strings.NewReader("这是完整的文本内容")
	data, err := io.ReadAll(reader)
	if err != nil {
		panic(err)
	}
	fmt.Printf("读取全部: %s\n", string(data))

	// io.ReadFull: 精确读取指定长度
	reader2 := strings.NewReader("Hello, World!")
	buf := make([]byte, 5)

	n, err := io.ReadFull(reader2, buf)
	if err != nil {
		panic(err)
	}
	fmt.Printf("精确读取 %d 字节: %s\n", n, string(buf))

	// 如果数据不足会返回 io.ErrUnexpectedEOF
	shortReader := strings.NewReader("Hi")
	bigBuf := make([]byte, 10)

	n, err = io.ReadFull(shortReader, bigBuf)
	if err == io.ErrUnexpectedEOF {
		fmt.Printf("数据不足,只读取了 %d 字节: %s\n", n, string(bigBuf[:n]))
	}
}

MultiReader 和 MultiWriter

package main

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

func main() {
	// io.MultiReader: 将多个 Reader 串联
	r1 := strings.NewReader("第一部分 ")
	r2 := strings.NewReader("第二部分 ")
	r3 := strings.NewReader("第三部分")

	multiReader := io.MultiReader(r1, r2, r3)

	result, err := io.ReadAll(multiReader)
	if err != nil {
		panic(err)
	}
	fmt.Printf("MultiReader 结果: %s\n", string(result))

	// io.MultiWriter: 同时写入多个 Writer
	var buf1, buf2 bytes.Buffer

	multiWriter := io.MultiWriter(&buf1, &buf2)

	n, err := multiWriter.Write([]byte("同时写入两个缓冲区"))
	if err != nil {
		panic(err)
	}
	fmt.Printf("写入字节数: %d\n", n)
	fmt.Printf("buf1: %s\n", buf1.String())
	fmt.Printf("buf2: %s\n", buf2.String())
}

总结

功能 函数/类型 说明
复制 io.Copy 从 Reader 复制到 Writer
读取全部 io.ReadAll 读取所有数据到内存
限制读取 io.LimitReader 限制最大读取字节数
多路读取 io.MultiReader 串联多个 Reader
多路写入 io.MultiWriter 同时写入多个 Writer
分流读取 io.TeeReader 读取时同时备份
区域读取 io.SectionReader 读取指定区域
管道 io.Pipe 内存管道通信
如有疑问关注公众号给我留言
wx

关注公众号

©2017-2023 鲁ICP备17023316号-1 Powered by Hugo