golang 下载大文件流

发布时间:2024-12-23 06:46:31

在golang开发中,有时需要下载大文件流,即通过网络从服务器下载大文件,而不是一次性将整个文件加载到内存中。这样可以避免内存被占用过多,提高效率。本文将介绍如何使用golang下载大文件流。

1. 创建HTTP客户端

首先,我们需要创建一个HTTP客户端来发送GET请求获取文件流。在golang中,可以使用标准库的"net/http"来实现。下面是一个简单的示例:

package main

import (
    "fmt"
    "net/http"
    "os"
)

func main() {
    url := "http://example.com/largefile.zip"

    // 创建HTTP请求
    resp, err := http.Get(url)
    if err != nil {
        fmt.Println("下载失败:", err)
        os.Exit(1)
    }
    defer resp.Body.Close()

    // 检查状态码
    if resp.StatusCode != http.StatusOK {
        fmt.Println("下载失败:", resp.Status)
        os.Exit(1)
    }

    // 处理文件流
    // ...
}

2. 处理文件流

在上述代码中,我们通过http.Get方法发送GET请求,获取到了服务器返回的响应resp。我们首先要检查响应的状态码,如果不是200,则下载失败。

接下来,我们可以通过resp.Body获取到文件流。使用io.Copy方法可以很方便地将文件流复制到本地文件:

// 创建本地文件
file, err := os.Create("largefile.zip")
if err != nil {
    fmt.Println("创建文件失败:", err)
    os.Exit(1)
}
defer file.Close()

// 复制文件流到本地文件
_, err = io.Copy(file, resp.Body)
if err != nil {
    fmt.Println("复制文件流失败:", err)
    os.Exit(1)
}

3. 下载进度监控

以上代码可以实现简单的大文件下载功能,但在实际应用中,我们可能需要显示下载进度给用户。可以通过自定义一个实现了io.Writer接口的类型来监控下载进度:

type Progress struct {
    current int64
    total   int64
}

func (p *Progress) Write(b []byte) (n int, err error) {
    n = len(b)
    p.current += int64(n)
    progress := float64(p.current) / float64(p.total) * 100
    fmt.Printf("已下载 %.2f%%\n", progress)
    return
}

// ...

// 复制文件流到本地文件,并监控下载进度
progress := &Progress{total: resp.ContentLength}
_, err = io.Copy(io.MultiWriter(file, progress), resp.Body)
if err != nil {
    fmt.Println("复制文件流失败:", err)
    os.Exit(1)
}

通过以上代码,我们实现了一个自定义的Progress类型,其中Write方法会在每次写入文件时被调用,根据当前已下载的字节数和总字节数计算下载进度,并输出给用户。

以上便是使用golang下载大文件流的方法。通过创建HTTP客户端、处理文件流和添加下载进度监控,我们可以灵活地实现大文件的下载功能,并提供更好的用户体验。

相关推荐