Go 中 Gzip 与 json 搭配使用压缩数据
前言
在日常工作中,如果遇到数据量大的情况,在 db 中是不能直接存储某些字段的,一般会用 json 进行marshal 为 byte 再存入。但是如果此时占用空间依旧过大,则可以考虑再用 gzip 还进一步压缩。
Gzip 包
go标准库的gzip包中提供了两个操作,分别是压缩和解压
常量和变量
const (
NoCompression = flate.NoCompression
BestSpeed = flate.BestSpeed
BestCompression = flate.BestCompression
DefaultCompression = flate.DefaultCompression
)
var (
ErrChecksum = errors.New("gzip: invalid checksum")
ErrHeader = errors.New("gzip: invalid header")
)
type Header struct {
Comment string
Extra []byte
ModTime time.Time
Name string
OS byte
}
Gzip 用法
压缩
func Encode(input []byte) ([]byte, error) {
var buf bytes.Buffer
gzipWriter := gzip.NewWriter(&buf)
_, err := gzipWriter.Write(input)
if err != nil {
_ = gzipWriter.Close()
return nil, err
}
if err := gzipWriter.Close(); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
解压
func Decode(input []byte) ([]byte, error) {
bytesReader := bytes.NewReader(input)
gzipReader, err := gzip.NewReader(bytesReader)
if err != nil {
return nil, err
}
defer func() {
_ = gzipReader.Close()
}()
buf := new(bytes.Buffer)
if _, err := buf.ReadFrom(gzipReader); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
与 json 搭配使用
func MarshalToJsonWithGzip(jsonData anyStruct) []byte {
dataAfterMarshal, _ := json.Marshal(jsonData)
dataAfterGzip, err := gzip.Encode(dataAfterMarshal)
if err != nil {
return nil
}
return dataAfterGzip
}
func UnmarshalDataFromJsonWithGzip(msg []byte) (*anyStruct, error) {
dataAfterDecode, err := gzip.Decode(msg)
if err != nil {
return nil, err
}
data := &anyStruct{}
err = json.Unmarshal(dataAfterDecode, data)
if err != nil {
return nil, err
}
return data, nil
}
|