golang实现http下载

发布时间:2024-12-28 21:17:30

Go是一种现代的、静态类型的编程语言,由Google开发。它的主要特点是简洁、高效、安全和并发。Go语言在网络编程方面表现出色,可以轻松实现各种网络操作,包括HTTP下载。本文将介绍如何使用Go语言实现HTTP下载。

发起HTTP请求

要实现HTTP下载,首先需要发起HTTP请求,并获取到服务器返回的内容。在Go语言中,可以使用标准库中的net/http包来发起HTTP请求。下面是一个简单的示例代码:

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    url := "http://example.com/file.txt"
    resp, err := http.Get(url)
    if err != nil {
        fmt.Println("HTTP GET request failed:", err)
        return
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("Failed to read response body:", err)
        return
    }

    fmt.Println(string(body))
}

以上代码中,我们使用http.Get方法来发送GET请求,并获取到服务器返回的内容。resp.Body是一个ReadCloser接口,我们可以使用ioutil.ReadAll方法将其读取为字节数组。

保存下载文件

获取到服务器返回的内容后,我们可以将其保存为文件。在Go语言中,可以使用os包来创建和写入文件。下面是一个将HTTP响应保存为文件的示例代码:

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

func main() {
    url := "http://example.com/file.txt"
    resp, err := http.Get(url)
    if err != nil {
        fmt.Println("HTTP GET request failed:", err)
        return
    }
    defer resp.Body.Close()

    file, err := os.Create("file.txt")
    if err != nil {
        fmt.Println("Failed to create file:", err)
        return
    }
    defer file.Close()

    _, err = io.Copy(file, resp.Body)
    if err != nil {
        fmt.Println("Failed to save response body:", err)
        return
    }

    fmt.Println("File saved successfully")
}

以上代码中,我们使用os.Create方法创建一个新的文件,并使用io.Copy方法将响应体复制到文件中。这样就可以将HTTP响应保存为文件。

设置下载进度

实现基本的HTTP下载功能后,我们还可以扩展代码,添加下载进度的显示。在Go语言中,可以利用goroutine和channel来实现并发下载和进度更新。下面是一个实现下载进度显示的示例代码:

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

func downloadFile(url string, filepath string) error {
    resp, err := http.Get(url)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

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

    done := make(chan int64)
    go func() {
        n, _ := io.Copy(file, resp.Body)
        done <- n
    }()

    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()

    for {
        select {
        case <-ticker.C:
            fi, _ := file.Stat()
            fmt.Printf("Downloaded %d bytes...\n", fi.Size())
        case <-done:
            fi, _ := file.Stat()
            fmt.Printf("Download finished. Total size: %d bytes\n", fi.Size())
            return nil
        }
    }
}

func main() {
    url := "http://example.com/file.txt"
    filepath := "file.txt"

    err := downloadFile(url, filepath)
    if err != nil {
        fmt.Println("Failed to download file:", err)
        return
    }
}

以上代码中,我们首先使用goroutine将文件的复制操作放在后台进行。同时,使用time.NewTicker来定时获取文件的大小并输出下载进度。当文件复制完成后,将通过通道发送一个信号,表示下载已完成。

通过上述步骤,我们可以实现基本的HTTP下载、保存文件和显示下载进度的功能。以上示例代码只是最简单的实现方式,你可以根据自己的需求进行扩展和优化。

相关推荐