为了账号安全,请及时绑定邮箱和手机立即绑定

使用 io.Pipe() 读/写 golang 下载一个 zip 文件

使用 io.Pipe() 读/写 golang 下载一个 zip 文件

Go
郎朗坤 2022-04-20 17:39:36
我正在尝试使用 golang 中的 io.Pipe() 函数流式传输 zip 文件的字节。我正在使用管道阅读器读取 zip 中每个文件的字节,然后将它们流式传输并使用管道编写器将字节写入响应对象中。func main() {  r, w := io.Pipe() // go routine to make the write/read non-blocking  go func() {    defer w.Close()    bytes, err := ReadBytesforEachFileFromTheZip()     err := json.NewEncoder(w).Encode(bytes)    handleErr(err)  }()这不是一个有效的实现,而是我想要实现的结构。我不想使用 ioutil.ReadAll 因为文件会非常大,并且 Pipe() 将帮助我避免将所有数据放入内存。有人可以帮助使用 io.Pipe() 实现工作吗?
查看完整描述

1 回答

?
神不在的星期二

TA贡献1963条经验 获得超6个赞

我使用 golang io.Pipe() 使它工作。 Pipewriter 将字节以块的形式写入管道,而 pipeReader 读取器则从另一端写入。使用 go-routine 的原因是有一个非阻塞的写操作,而同时读取从管道发生。


注意:关闭管道写入器 (w.Close()) 以在流上发送 EOF 很重要,否则它不会关闭流。


func DownloadZip() ([]byte, error) {

    r, w := io.Pipe()


    defer r.Close()

    defer w.Close()


    zip, err := os.Stat("temp.zip")

    if err != nil{

        return nil, err

    }


    go func(){


        f, err := os.Open(zip.Name())

        if err != nil {

            return


        }


        buf := make([]byte, 1024)

        for {

            chunk, err := f.Read(buf)

            if err != nil && err != io.EOF {

                panic(err)

            }

            if chunk == 0 {

                break

            }


            if _, err := w.Write(buf[:chunk]); err != nil{

                return

            }


        }


        w.Close()

    }()


    body, err := ioutil.ReadAll(r)

    if err != nil {

        return nil, err

    }

    return body, nil


}

如果有人有其他方法,请告诉我。



查看完整回答
反对 回复 2022-04-20
  • 1 回答
  • 0 关注
  • 371 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号