I am also new to Go and have struggled a bit using github.com/pierrec/lz4
.
What I was misunderstanding is that calling Close()
on NewWriter
is not optional and failing to do so will lead to incorrect results. (I spent a lot of time banging my head against the wall for thinking this was optional and just a best-practice, as it is in closing file handlers, network connections, etc)
I wrote two wrapper versions for compressing/decompressing.
First, a generic reader/writer approach (similar to the example on the README, but without pipes) [playground]:
func compress(r io.Reader, w io.Writer) error {
zw := lz4.NewWriter(w)
_, err := io.Copy(zw, r)
if err != nil {
return err
}
// Closing is *very* important
return zw.Close()
}
func decompress(r io.Reader, w io.Writer) error {
zr := lz4.NewReader(r)
_, err := io.Copy(w, zr)
return err
}
If your data size is small and you don't need to/want to mess with buffers and just want to have uncompressed bytes in, compressed bytes out, (in a more "functional" fashion) this second version may be more convenient [playground]:
func compress(in []byte) ([]byte, error) {
r := bytes.NewReader(in)
w := &bytes.Buffer{}
zw := lz4.NewWriter(w)
_, err := io.Copy(zw, r)
if err != nil {
return nil, err
}
// Closing is *very* important
if err := zw.Close(); err != nil {
return nil, err
}
return w.Bytes(), nil
}
func decompress(in []byte) ([]byte, error) {
r := bytes.NewReader(in)
w := &bytes.Buffer{}
zr := lz4.NewReader(r)
_, err := io.Copy(w, zr)
if err != nil {
return nil, err
}
return w.Bytes(), nil
}