一个压缩接口实现

本文介绍了如何定义一个压缩接口,并分别实现了Zlib和Snappy两种压缩方式。Zlib提供了一种通用的压缩解决方案,而Snappy以其快速压缩和较低CPU占用率的特点,提供了更大的压缩比例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、首先定义一个压缩接口,以便支持不同的压缩方式

//压缩接口,压缩类需要实现以下两个方法
type Compressor interface {
  Compress(b []byte, c []byte) ([]byte, error)  //压缩数据
  Decompress(c []byte, b []byte) error          //解压缩数据
}


//工厂类,创建不同的压缩
func NewCompressor(compressFormat string) Compressor {
	compressFormat = strings.ToLower(compressFormat)
	if compressFormat == "snappy" {
		return NewSnappyCompressor()

	} else if compressFormat == "zlib" {
		return NewZlibCompressor()
	} else {
		return nil
	}
}



//封装一个全局读取函数,止到数据全部读完或超时
func ReadAll(conn io.Reader, data []byte) error {
  left:= len(data)
  for left > 0 {
     n, err:= conn.Read(data)
     if n == left && err == nil {
        return nil
     }

     if n > 0 {
         data = data[n:]
         left -= n
     }

     if err != nil {
        return err
     }
  }

  return nil
}

二、实现Zlib压缩

package compress

import (
	"compress/zlib"
	"io"
	"bytes"
	"io/ioutil"
	"fmt"
)


//创建压缩接口工厂类
func NewZlibCompressor() Compressor  {
	fc:= &zlibCompressor{}
	fc.reader = newZlibReader()
	var err error
	fc.writer, err = zlib.NewWriterLevel(ioutil.Discard, zlib.BestSpeed)
	if err != nil {
		panic(err)
	}
	return fc
}


//该类需要实现压缩接口的两个方法
type zlibCompressor struct {
	writer *zlib.Writer
	reader io.ReadCloser
}

func newZlibReader() (reader io.ReadCloser)  {
	w:= bytes.NewBuffer(nil)
	cw:= zlib.NewWriter(w)
	cw.Write(nil)
	cw.Flush()

	reader, _ = zlib.NewReader(bytes.NewReader(w.Bytes()))
	return
}

//实现压缩方法
func (fc *zlibCompressor) Compress(b []byte, c []byte) ([]byte, error)  {
	wb:= bytes.NewBuffer(c)
	fc.writer.Reset(wb)
	n, err:= fc.writer.Write(b)
	if err != nil {
		return nil, err
	}

	if n!= len(b) {
		return nil, fmt.Errorf("errNotFullyCompressed")
	}

	fc.writer.Flush()
	return wb.Bytes(), nil
}


//实现解压方法
func (fc *zlibCompressor) Decompress(c []byte, b []byte) error  {
	fc.reader.(zlib.Resetter).Reset(bytes.NewReader(c), nil)
	return ReadAll(fc.reader, b)
}

三、实现snappy压缩,该压缩速度最快,cpu占用率低,压缩比例相对更大些

package compress

import (
	"github.com/golang/snappy"
	"os"
	"bytes"
	"fmt"
)

func NewSnappyCompressor() Compressor {
	return &snappyCompressor{
		writer: snappy.NewWriter(os.Stdout),
		reader: snappy.NewReader(os.Stdin),
	}
}

type snappyCompressor struct {
	writer *snappy.Writer
	reader *snappy.Reader
}

func (sc *snappyCompressor) Compress(b []byte, c []byte) ([]byte, error) {
	wb:= bytes.NewBuffer(c)
	sc.writer.Reset(wb)
	n, err:= sc.writer.Write(b)
	if err != nil {
		return nil, err
	}

	if n!= len(b) {
		return nil, fmt.Errorf("errNotFullyCompressed")
	}

	sc.writer.Flush()
	return wb.Bytes(), nil
}

func (sc *snappyCompressor) Decompress(c []byte, b []byte) error {
	sc.reader.Reset(bytes.NewReader(c))
	return ReadAll(sc.reader, b)
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值