Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

io

go

I'm writing a long running task which fetch from mongodb (using mgo) multiple times. Then write it to an xlsx file using this module. Then read it again using os.Open then store it to my ftp server.

Stor function consume my memory so much, So I think there should be a way not to save file but pass my data from xlsx.Write to ftp.Store directly. (If I can stream simultaneously would be perfect because I don't have to hold all of my documents in server's memory before send them to Stor function)

These are prototype of the functions

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

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

like image 532
Methuz Kaewsai-kao Avatar asked Jul 07 '15 04:07

Methuz Kaewsai-kao


People also ask

What is io writer?

The io.Writer interface is used by many packages in the Go standard library and it represents the ability to write a byte slice into a stream of data. More generically allows you to write data into something that implements the io.Writer interface.

What is io ReadCloser?

You may use it when you have Read and Close methods, an example to show that you may use one common function to work with different types using io.ReadCloser : package main import ( "fmt" "io" "log" "os" ) func main() { f, err := os.Open("./main.go") if err != nil { log.Fatal(err) } doIt(f) doIt(os.Stdin) } func doIt( ...

What is io Golang?

The io package specifies the io. Reader interface, which represents the read end of a stream of data. The Go standard library contains many implementations of this interface, including files, network connections, compressors, ciphers, and others.


2 Answers

You want to use io.Pipe. You can do:

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

You might want to writer.CloseWithError(err) if xlsx.Write returns an error without closing the writer.

like image 70
hobbs Avatar answered Oct 28 '22 04:10

hobbs


you can use 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 {}
like image 22
Arthur Wang Avatar answered Oct 28 '22 04:10

Arthur Wang