• 简体中文
  • Example: io.ReadAll

    io.ReadAll 用于从 io.Reader 中读取全部数据,并返回一个包含完整内容的 []byte

    它适用于数据规模可控、可以一次性加载到内存的场景,例如:

    • 读取配置文件
    • 解析 HTTP 响应
    • 加载 JSON 数据
    • 处理测试数据

    它不适合处理大型文件、长连接或无限流式数据(例如 TCP Socket),因为 io.ReadAll 会持续读取直到 EOF,并将全部内容保存在内存中,可能导致较高的内存占用。

    简明示例

    从一个字符串 Reader 中一次性读取全部数据,并打印输出。

    package main
    
    import (
    	"fmt"
    	"io"
    	"strings"
    )
    
    func main() {
    	// 1. 创建 Reader,模拟数据源
    	src := strings.NewReader("Hello, io.ReadAll from gobase.net.\n")
    
    	// 2. 读取 Reader 中的全部数据
    	data, err := io.ReadAll(src)
    	if err != nil {
    		fmt.Printf("读取失败: %v\n", err)
    		return
    	}
    
    	// 3. data 包含 Reader 返回的全部字节
    	fmt.Printf("%s", data)
    }

    读取配置文件

    在生产环境中,io.ReadAll 常用于加载小型本地资源,例如配置文件、证书、模板文件或内嵌资源。

    示例代码:

    package main
    
    import (
    	"fmt"
    	"io"
    	"os"
    )
    
    func main() {
    	// 1. 打开配置文件
    	file, err := os.Open("config.json")
    	if err != nil {
    		fmt.Printf("打开文件失败: %v\n", err)
    		return
    	}
    	defer file.Close()
    
    	// 2. 将文件完整读取到内存
    	content, err := io.ReadAll(file)
    	if err != nil {
    		fmt.Printf("读取文件失败: %v\n", err)
    		return
    	}
    
    	// 3. 处理配置数据
    	fmt.Printf("配置文件大小: %d 字节\n", len(content))
    	fmt.Println(string(content))
    }

    对于 20 KB 左右的 config.json 这类小型配置文件,完整加载到内存的成本非常低。

    相比复杂的流式处理方式,io.ReadAll 提供了更简单的实现和更低的维护成本,这通常是生产系统中的合理选择。


    读取 HTTP 响应体

    调用返回内容大小可控的 HTTP API 时,io.ReadAll 是最常见的响应处理方式之一。

    示例代码:

    package main
    
    import (
    	"fmt"
    	"io"
    	"net/http"
    )
    
    func main() {
    	resp, err := http.Get("https://hacker-news.firebaseio.com/v0/item/8863.json?print=pretty")
    	if err != nil {
    		fmt.Printf("请求失败: %v\n", err)
    		return
    	}
    	defer resp.Body.Close()
    
    	// 限制最大读取大小,避免异常响应占用过多内存
    	body, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20))
    	if err != nil {
    		fmt.Printf("读取响应体失败: %v\n", err)
    		return
    	}
    
    	fmt.Printf("响应大小: %d 字节\n", len(body))
    	fmt.Println(string(body))
    }

    这里通过 io.LimitReader 将最大读取量限制为 1 MB,避免服务端异常返回大量数据导致客户端内存压力。