■实例说明
我们在Linux中经常会用到后缀为.gz的文件,它们就是GZIP格式的。现今已经成为Internet 上使用非常普遍的一种数据压缩格式
1)使用gzip压缩数据
2)使用gzip解压缩数据
■实例代码
[Golang] 纯文本查看 复制代码 package main
import (
"bytes"
"compress/gzip"
"fmt"
"io/ioutil"
"sync"
)
// GzipCompress gzip解压缩
type GzipCompress struct {
readerPool sync.Pool
writerPool sync.Pool
}
// Compress gzip压缩
func (c *GzipCompress) Compress(in []byte) ([]byte, error) {
if len(in) == 0 {
return in, nil
}
buffer := &bytes.Buffer{}
z, ok := c.writerPool.Get().(*gzip.Writer)
if !ok {
z = gzip.NewWriter(buffer)
} else {
z.Reset(buffer)
}
defer c.writerPool.Put(z)
if _, err := z.Write(in); err != nil {
return nil, err
}
if err := z.Close(); err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
// Decompress gzip解压
func (c *GzipCompress) Decompress(in []byte) ([]byte, error) {
if len(in) == 0 {
return in, nil
}
br := bytes.NewReader(in)
z, ok := c.readerPool.Get().(*gzip.Reader)
defer func() {
if z != nil {
c.readerPool.Put(z)
}
}()
if !ok {
gr, err := gzip.NewReader(br)
if err != nil {
return nil, err
}
z = gr
} else {
if err := z.Reset(br); err != nil {
return nil, err
}
}
out, err := ioutil.ReadAll(z)
if err != nil {
return nil, err
}
return out, nil
}
func main() {
// 对于比较短,或者没有啥重复部分的内容,gzip压缩后,内容可能比以前内容都大,因为gzip内部会有一些固定结构
str := "12345678901234567890123456789012345678901234567890" +
"12345678901234567890123456789012345678901234567890" +
"12345678901234567890" // 现在是120,压缩后是36
//str = "123456789012345678901234567890" // 现在是30,压缩后是36
//str = "1234567890abcdefghigklmnopqrstuvwxyz" // 现在是36,压缩后是60
fmt.Printf("origin size:%d\n", len([]byte(str)))
gz := GzipCompress{}
gzBytes, _ := gz.Compress([]byte(str))
fmt.Printf("gz after size:%d\n", len(gzBytes))
fmt.Println(gzBytes)
newBytes, _ := gz.Decompress(gzBytes)
fmt.Printf("Decompress str:%s\n", string(newBytes))
}
|