【问题标题】:How do I connect io.Reader and io.Writer?如何连接 io.Reader 和 io.Writer?
【发布时间】:2018-06-18 09:45:50
【问题描述】:

我正在编写一个长时间运行的任务,该任务多次从 mongodb(使用 mgo)获取。然后使用this module 将其写入 xlsx 文件。然后使用os.Open 再次读取它,然后将其存储到我的 ftp 服务器。

Stor 函数非常消耗我的内存,所以我认为应该有一种方法不保存文件,而是将我的数据从 xlsx.Write 直接传递到 ftp.Store。 (如果我可以同时流式传输将是完美的,因为在将它们发送到 Stor 函数之前,我不必将所有文档都保存在服务器的内存中)

这些是函数的原型

func (f *File) Write(writer io.Writer) (err error)xlsl

func (ftp *FTP) Stor(path string, r io.Reader) (err error)ftp

【问题讨论】:

    标签: go io


    【解决方案1】:

    您想使用io.Pipe。你可以这样做:

    reader, writer := io.Pipe()
    errChan := make(chan error)
    go func() {
        errChan <- myFTP.Stor(path, reader)
    }()
    err := myXLS.Write(writer)
    // handle err
    err = <-errChan
    // handle err
    

    如果xlsx.Write 在不关闭编写器的情况下返回错误,您可能需要writer.CloseWithError(err)

    【讨论】:

    • io.Pipe() 不返回 io.Writer 和 io.Reader,而是返回 *PipeReader, *PipeWriter。它们是一样的吗?
    • @MethuzKaewsai-kao: io.Reader 是一个接口,*PipeReader 是实现io.Reader 接口的具体类型。 (作者也是如此。)所以是的,您可以在任何接受io.Reader 的地方使用*PipeReader
    【解决方案2】:

    你可以使用bytes.Buffer:

    func uploadFileToQiniu(file *xlsx.File) (key string, err error) {
        key = fmt.Sprintf("%s.xlsx", util.SerialNumber())
        log.Debugf("file key is %s", key)
    
        log.Debug("start to write file to a writer")
        buf := new(bytes.Buffer)
        err = file.Write(buf)
        if err != nil {
            log.Errorf("error caught when writing file: %v", err)
            return
        }
    
        size := int64(buf.Len())
        log.Debugf("file size is %d", size)
        err = Put(key, size, buf)
        if err != nil {
            log.Errorf("error caught when uploading file: %v", err)
        }
        return key, nil
    }
    
    func Put(key string, size int64, reader io.Reader) error {}
    

    【讨论】:

      猜你喜欢
      • 2022-01-10
      • 2018-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-03
      • 2019-02-04
      • 2015-12-31
      相关资源
      最近更新 更多