代码之家  ›  专栏  ›  技术社区  ›  psbits

使用io下载zip文件。管道()读/写golang

  •  2
  • psbits  · 技术社区  · 8 年前

    我正在尝试使用io流式输出zip文件的字节。golang中的Pipe()函数。我使用管道读取器读取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的工作实现吗。这是管道吗?

    1 回复  |  直到 8 年前
        1
  •  0
  •   psbits    8 年前

    我使用golang io.Pipe()使其工作。Pipewriter将字节以块的形式写入管道,而pipeReader读取器则从另一端写入。使用go例程的原因是在管道中同时进行读取时,具有非阻塞写入操作。

    注意:关闭管道编写器(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
    
    }