douaoren4402
2016-11-10 19:59
浏览 331
已采纳

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

I am trying to stream out bytes of a zip file using io.Pipe() function in golang. I am using pipe reader to read the bytes of each file in the zip and then stream those out and use the pipe writer to write the bytes in the response object.

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)
  }()

This is not a working implementation but a structure of what I am trying to achieve. I don't want to use ioutil.ReadAll since the file is going to be very large and Pipe() will help me avoid bringing all the data into memory. Can someone help with a working implementation using io.Pipe() ?

图片转代码服务由CSDN问答提供 功能建议

我正在尝试使用golang中的io.Pipe()函数流式处理zip文件的字节。 我正在使用管道读取器读取zip中每个文件的字节,然后将其流式传输并使用管道写入器将字节写入响应对象中。

  func main  (){
r,w:= io.Pipe()
 //执行例程以使写入/读取无阻塞
 go func(){
 
延迟w.Close()
 
 字节,错误:= ReadBytesforEachFileFromTheZip()
错误:= json.NewEncoder(w)。编码(字节)
 handleErr(错误)
}()
   
 
 <  p>这不是一个可行的实现,而是我试图实现的结构。 我不想使用ioutil.ReadAll,因为文件将非常大,而Pipe()将帮助我避免将所有数据带入内存。 有人可以使用io.Pipe()帮助工作实现吗? 
 
  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dongnao2048 2016-11-11 22:12
    已采纳

    I made it work using golang io.Pipe().The Pipewriter writes byte to the pipe in chunks and the pipeReader reader from the other end. The reason for using a go-routine is to have a non-blocking write operation while simultaneous reads happen form the pipe.

    Note: It's important to close the pipe writer (w.Close()) to send EOF on the stream otherwise it will not close the stream.

    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
    
    }
    

    Please let me know if someone has another way of doing it.

    已采纳该答案
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题