Search code examples
gozipmultipartform-data

Zip a slice of byte into another slice in Golang


I want to achieve exactly opposite of the solution given here, zipping a slice of byte into another slice of byte -

Convert zipped []byte to unzip []byte golang code

Something like -

func ZipBytes(unippedBytes []byte) ([]byte, error) {
// ...
}

[I am going to upload that zipped file as multipart form data for a POST request]


Solution

  • You can compress directly into memory using a bytes.Buffer.

    The following example uses compress/zlib since it is the opposite of the example given in the question. Depending on your use case you could easily change it to compress/gzip as well (very similar APIs).

    package data_test
    
    import (
        "bytes"
        "compress/zlib"
        "io"
        "testing"
    )
    
    func compress(buf []byte) ([]byte, error) {
        var out bytes.Buffer
        w := zlib.NewWriter(&out)
        if _, err := w.Write(buf); err != nil {
            return nil, err
        }
        if err := w.Close(); err != nil {
            return nil, err
        }
        return out.Bytes(), nil
    }
    
    func decompress(buf []byte) (_ []byte, e error) {
        r, err := zlib.NewReader(bytes.NewReader(buf))
        if err != nil {
            return nil, err
        }
        defer func() {
            if err := r.Close(); e == nil {
                e = err
            }
        }()
        return io.ReadAll(r)
    }
    
    func TestRoundtrip(t *testing.T) {
        want := []byte("test data")
    
        zdata, err := compress(want)
        if err != nil {
            t.Fatalf("compress: %v", err)
        }
        got, err := decompress(zdata)
        if err != nil {
            t.Fatalf("decompress: %v", err)
        }
        if !bytes.Equal(want, got) {
            t.Errorf("roundtrip: got = %q; want = %q", got, want)
        }
    }