Golang中的`io.Copy()`使用场景

io.Copy() 是 Go 语言标准库 io 包中一个非常核心和常用的函数。它的基本功能是从一个源(src)读取数据并写入到一个目标(dst ,直到读取到 EOF 或发生错误。

go 复制代码
func Copy(dst Writer, src Reader) (written int64, err error)

io.Copy() 的核心价值在于它提供了一个高效、简洁、通用 的方式来处理数据流的复制,而无需关心具体的数据类型或底层实现,只要它们实现了 io.Readerio.Writer 接口。

1、文件操作
go 复制代码
// 复制文件
func copyFile(src, dst string) error {
    sourceFile, err := os.Open(src)
    if err != nil {
        return err
    }
    defer sourceFile.Close()

    destFile, err := os.Create(dst)
    if err != nil {
        return err
    }
    defer destFile.Close()

    _, err = io.Copy(destFile, sourceFile)
    return err
}

这里需要注意的是,如果destFile不是APPEND模式,那么第二次调用io.Copy会覆盖原先的内容。

2. HTTP 请求与响应处理

net/http 包中,io.Copy() 非常常见。

将 HTTP 响应体写入文件或另一个 Writer

go 复制代码
resp, err := http.Get("https://example.com/data")
if err != nil {
    // 处理错误
}
defer resp.Body.Close()

// 将响应体直接写入文件
file, _ := os.Create("downloaded_data")
defer file.Close()
io.Copy(file, resp.Body)

// 或者写入 bytes.Buffer
var buf bytes.Buffer
io.Copy(&buf, resp.Body)

在 HTTP 代理或中间件中转发请求/响应体

go 复制代码
// 在反向代理中,将后端服务的响应原样返回给客户端
resp, err := backendClient.Do(req)
if err != nil {
    // 处理错误
}
defer resp.Body.Close()

// 将后端响应头复制到客户端响应
for k, v := range resp.Header {
    w.Header()[k] = v
}
w.WriteHeader(resp.StatusCode)

// 使用 io.Copy 将后端响应体流式传输给客户端
io.Copy(w, resp.Body) // w 是 http.ResponseWriter (实现了 io.Writer)
3. 进程间通信 (IPC)

通过管道 (io.Pipe) 在 goroutine 之间或父子进程间传递数据。

go 复制代码
// 创建管道
reader, writer := io.Pipe()

// 在一个 goroutine 中写入数据
go func() {
    defer writer.Close()
    fmt.Fprintln(writer, "Hello from goroutine!")
}()

// 在主 goroutine 中读取并通过 io.Copy 输出到 stdout
io.Copy(os.Stdout, reader)
4. 网络编程

在网络连接(net.Conn)之间复制数据。

go 复制代码
// 简单的 TCP 代理/转发
func proxyConn(srcConn, dstConn net.Conn) {
    defer srcConn.Close()
    defer dstConn.Close()

    // 同时双向复制
    var wg sync.WaitGroup
    wg.Add(2)

    go func() {
        defer wg.Done()
        io.Copy(dstConn, srcConn) // 客户端 -> 服务端
    }()

    go func() {
        defer wg.Done()
        io.Copy(srcConn, dstConn) // 服务端 -> 客户端
    }()

    wg.Wait()
}
5. 数据缓冲与转换

结合 bytes.Bufferstrings.Reader 进行内存中的数据操作。

go 复制代码
// 将字符串内容复制到 Buffer
str := "Hello, World!"
reader := strings.NewReader(str)
var buf bytes.Buffer
io.Copy(&buf, reader)
data := buf.Bytes()

// 将 Buffer 内容复制到另一个 Writer
io.Copy(someWriter, &buf)
6. 压缩与解压缩

compress/gzip 等包结合使用。

go 复制代码
// 压缩文件
func compressFile(inputFile, outputFile string) error {
    inFile, _ := os.Open(inputFile)
    defer inFile.Close()
    outFile, _ := os.Create(outputFile)
    defer outFile.Close()

    gzipWriter := gzip.NewWriter(outFile)
    defer gzipWriter.Close()

    // 将原始文件内容通过 gzip 压缩器写入输出文件
    _, err := io.Copy(gzipWriter, inFile)
    return err
}
7. 日志处理

将程序的标准输出/错误重定向到日志文件。

go 复制代码
logFile, _ := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
defer logFile.Close()

// 将标准错误重定向到日志文件 (需要在 goroutine 中运行)
go func() {
    io.Copy(logFile, os.Stderr)
}()
相关推荐
2501_941875283 小时前
从配置中心到动态管理的互联网工程语法演进与多语言实践分享
开发语言·python
hfywmsj3 小时前
广州餐饮铺位招租决策模型:多因子选址系统设计
开发语言·人工智能·python·广州餐饮铺位招租
vx-Biye_Design3 小时前
SSM伴侣动物伴护星小程序06330-计算机课程设计、毕业设计
spring boot·后端·elasticsearch·小程序·架构·课程设计·idea
努力的lpp5 小时前
php反序列化一(大白话版)
开发语言·web安全·php·ctf·反序列化
2分钟速写快排5 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
菜鸟~noob2335 小时前
【电子战】第03篇:CFAR(恒虚警)处理【含matlab代码】
开发语言·matlab
面向Google编程5 小时前
Apache Iceberg Variant 类型:v3 半结构化数据不再「二选一」
大数据·后端
jason成都6 小时前
Spring WebFlux 适配达梦新方案|dm‑r2dbc:Netty 异步传输的实验性 R2DBC 驱动
java·后端·spring
泡海椒6 小时前
内置SPI函数库详解:JQuick-Java Builtin工具类实战用法
java·开发语言·python
hqyjzsb6 小时前
零 AI 项目经验,学 Python 转型 AI 的正确顺序是什么?
开发语言·人工智能·python·算法·职场和发展·数据挖掘·数据分析