I'm trying, just for fun, to connect a gzip Writer directly to a gzip Reader, so I could write to the Writer and read from the Reader on the fly. I expected to read exactly what I wrote. I'm using gzip but I'd like to use this method also with crypto/aes, I suppose it should work very similar and it could be used with other reader/writers like jpeg, png...
This is my best option, that is not working, but I hope you can see what I mean: http://play.golang.org/p/7qdUi9wwG7
package main
import (
"bytes"
"compress/gzip"
"fmt"
)
func main() {
s := []byte("Hello world!")
fmt.Printf("%s
", s)
var b bytes.Buffer
gz := gzip.NewWriter(&b)
ungz, err := gzip.NewReader(&b)
fmt.Println("err: ", err)
gz.Write(s)
gz.Flush()
uncomp := make([]byte, 100)
n, err2 := ungz.Read(uncomp)
fmt.Println("err2: ", err2)
fmt.Println("n: ", n)
uncomp = uncomp[:n]
fmt.Printf("%s
", uncomp)
}
It seems that gzip.NewReader(&b)
is trying to read immediately and a EOF is returned.
You'll need to do two things to make it work
Here is what that looks like
func main() {
s := []byte("Hello world!")
fmt.Printf("%s
", s)
in, out := io.Pipe()
gz := gzip.NewWriter(out)
go func() {
ungz, err := gzip.NewReader(in)
fmt.Println("err: ", err)
uncomp := make([]byte, 100)
n, err2 := ungz.Read(uncomp)
fmt.Println("err2: ", err2)
fmt.Println("n: ", n)
uncomp = uncomp[:n]
fmt.Printf("%s
", uncomp)
}()
gz.Write(s)
gz.Flush()
}
Use a pipe. For example,
func Pipe() (*PipeReader, *PipeWriter)
Pipe
creates a synchronous in-memory pipe. It can be used to connect code expecting an io.Reader with code expecting an io.Writer. Reads on one end are matched with writes on the other, copying data directly between the two; there is no internal buffering. It is safe to call Read and Write in parallel with each other or with Close. Close will complete once pending I/O is done. Parallel calls to Read, and parallel calls to Write, are also safe: the individual calls will be gated sequentially.