如何连接 io.Reader 和 io.Writer?

How do I connect io.Reader and io.Writer?

我正在写一个很长的 运行 任务,它多次从 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

您想使用 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

您可能希望 writer.CloseWithError(err) 如果 xlsx.Write returns 出现错误而不关闭编写器。

您可以使用 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 {}