douhuigan8063 2014-03-15 08:20
浏览 275
已采纳

下载文件时如何打印字节? -golang

I'm wondering if it's possible to count and print the number of bytes downloaded while the file is being downloaded.

out, err := os.Create("file.txt")
    defer out.Close()
    if err != nil {
        fmt.Println(fmt.Sprint(err) )

        panic(err)
    }
    resp, err := http.Get("http://example.com/zip")
    defer resp.Body.Close()
    if err != nil {
        fmt.Println(fmt.Sprint(err) )
        panic(err)
    }

    n, er := io.Copy(out, resp.Body)
    if er != nil {
        fmt.Println(fmt.Sprint(err) )
    }
    fmt.Println(n, "bytes ")
  • 写回答

4条回答 默认 最新

  • duanmao1975 2014-03-15 10:39
    关注

    If I understand you correctly, you wish to display the number of bytes read, while the data is transferring. Presumably to maintain some kind of a progress bar or something. In which case, you can use Go's compositional data structures to wrap the reader or writer in a custom io.Reader or io.Writer implementation.

    It simply forwards the respective Read or Write call to the underlying stream, while doing some additional work with the (int, error) values returned by them. Here is an example you can run on the Go playground.

    package main
    
    import (
        "bytes"
        "fmt"
        "io"
        "os"
        "strings"
    )
    
    // PassThru wraps an existing io.Reader.
    //
    // It simply forwards the Read() call, while displaying
    // the results from individual calls to it.
    type PassThru struct {
        io.Reader
        total int64 // Total # of bytes transferred
    }
    
    // Read 'overrides' the underlying io.Reader's Read method.
    // This is the one that will be called by io.Copy(). We simply
    // use it to keep track of byte counts and then forward the call.
    func (pt *PassThru) Read(p []byte) (int, error) {
        n, err := pt.Reader.Read(p)
        pt.total += int64(n)
    
        if err == nil {
            fmt.Println("Read", n, "bytes for a total of", pt.total)
        }
    
        return n, err
    }
    
    func main() {
        var src io.Reader    // Source file/url/etc
        var dst bytes.Buffer // Destination file/buffer/etc
    
        // Create some random input data.
        src = bytes.NewBufferString(strings.Repeat("Some random input data", 1000))
    
        // Wrap it with our custom io.Reader.
        src = &PassThru{Reader: src}
    
        count, err := io.Copy(&dst, src)
        if err != nil {
            fmt.Println(err)
            os.Exit(1)
        }
    
        fmt.Println("Transferred", count, "bytes")
    }
    

    The output it generates is this:

    Read 512 bytes for a total of 512
    Read 1024 bytes for a total of 1536
    Read 2048 bytes for a total of 3584
    Read 4096 bytes for a total of 7680
    Read 8192 bytes for a total of 15872
    Read 6128 bytes for a total of 22000
    Transferred 22000 bytes
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 C#调用python代码(python带有库)
  • ¥15 矩阵加法的规则是两个矩阵中对应位置的数的绝对值进行加和
  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)
  • ¥20 怎么在stm32门禁成品上增加查询记录功能
  • ¥15 Source insight编写代码后使用CCS5.2版本import之后,代码跳到注释行里面
  • ¥50 NT4.0系统 STOP:0X0000007B