- flate
- gzip
- bzip2
- lzw
- zlib
flate
flate包实现了deflate压缩数据格式,参见RFC 1951。gzip包和zlib包实现了对基于deflate的文件格式的访问。
Constants
const (
NoCompression = 0
BestSpeed = 1
BestCompression = 9
DefaultCompression = -1
)
type CorruptInputError
type CorruptInputError int64
CorruptInputError表示在输入的指定偏移量位置存在损坏。
func (CorruptInputError) Error
func (e CorruptInputError) Error() string
type InternalError
type InternalError string
InternalError表示flate数据自身的错误。
func (InternalError) Error
func (e InternalError) Error() string
type ReadError
type ReadError struct {
Offset int64 // 错误出现的位置(字节偏移量)
Err error // 下层的读取操作返回的错误
}
ReadError代表在读取输入流时遇到的错误。
func (*ReadError) Error
func (e *ReadError) Error() string
type WriteError
type WriteError struct {
Offset int64 // 错误出现的位置(字节偏移量)
Err error // 下层的写入操作返回的错误
}
WriteError代表在写入输出流时遇到的错误。
func (*WriteError) Error
func (e *WriteError) Error() string
type Reader
type Reader interface {
io.Reader
io.ByteReader
}
NewReader真正需要的接口。如果提供的Io.Reader没有提供ReadByte方法,NewReader函数会自行添加缓冲。
func NewReader
func NewReader(r io.Reader) io.ReadCloser
NewReader返回一个从r读取并解压数据的io.ReadCloser。调用者有责任在读取完毕后调用返回值的Close方法。
func NewReaderDict
func NewReaderDict(r io.Reader, dict []byte) io.ReadCloser
NewReaderDict类似NewReader,但会使用预设的字典初始化返回的Reader。
返回的Reader表现的好像原始未压缩的数据流以该字典起始(并已经被读取)。NewReaderDict用于读取NewWriterDict压缩的数据。
type Writer
type Writer struct {
d compressor
dict []byte
}
Writer将提供给它的数据压缩后写入下层的io.Writer接口。
func NewWriter
func NewWriter(w io.Writer, level int) (*Writer, error)
NewWriter返回一个压缩水平为level的Writer。
和zlib包一样,level的范围是1(BestSpeed)到9 (BestCompression)。值越大,压缩效果越好,但也越慢;level为0表示不尝试做任何压缩,只添加必需的deflate框架;level为-1时会使用默认的压缩水平;如果level在[-1, 9]范围内,error返回值将是nil,否则将返回非nil的错误值。
func NewWriterDict
func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error)
NewWriterDict类似NewWriter,但会使用预设的字典初始化返回的Writer。
返回的Writer表现的好像已经将原始、未压缩数据dict(压缩后未产生任何数据的)写入w了,使用w压缩的数据只能被使用同样的字典初始化生成的Reader接口解压缩。(类似加解密的初始向量/密钥)
func (*Writer) Reset
func (w *Writer) Reset(dst io.Writer)
Reset将w重置,丢弃当前的写入状态,并将下层输出目标设为dst。效果上等价于将w设为使用dst和w的压缩水平、字典重新调用NewWriter或NewWriterDict返回的*Writer。
func (*Writer) Write
func (w *Writer) Write(data []byte) (n int, err error)
Write向w写入数据,最终会将压缩后的数据写入下层io.Writer接口。
func (*Writer) Flush
func (w *Writer) Flush() error
Flush将缓冲中的压缩数据刷新到下层io.Writer接口中。
本方法主要用在传输压缩数据的网络连接中,以保证远端的接收者可以获得足够的数据来重构数据报。Flush会阻塞直到所有缓冲中的数据都写入下层io.Writer接口后才返回。如果下层的io.Writetr接口返回一个错误,Flush也会返回该错误。在zlib包的术语中,Flush方法等价于Z_SYNC_FLUSH。
func (*Writer) Close
func (w *Writer) Close() error
Close刷新缓冲并关闭w。
gzip
gzip包实现了gzip格式压缩文件的读写,参见RFC 1952。
Constants
const (
NoCompression = flate.NoCompression
BestSpeed = flate.BestSpeed
BestCompression = flate.BestCompression
DefaultCompression = flate.DefaultCompression
)
这些常量都是拷贝自flate包,因此导入"compress/gzip"后,就不必再导入"compress/flate"了。
Variables
var (
// 当读取的gzip数据的校验和错误时,会返回ErrChecksum
ErrChecksum = errors.New("gzip: invalid checksum")
// 当读取的gzip数据的头域错误时,会返回ErrHeader
ErrHeader = errors.New("gzip: invalid header")
)
type Header
type Header struct {
Comment string // 注释
Extra []byte // 额外数据
ModTime time.Time // 修改时间go
Name string // 文件名
OS byte // 操作系统类型
}
gzip文件保存一个头域,提供关于被压缩的文件的一些元数据。该头域作为Writer和Reader类型的一个可导出字段,可以提供给调用者访问。
type Reader
type Reader struct {
Header // valid after NewReader or Reader.Reset
r flate.Reader
decompressor io.ReadCloser
digest uint32 // CRC-32, IEEE polynomial (section 8)
size uint32 // Uncompressed size (section 2.3.1)
buf [512]byte
err error
multistream bool
}
Reader类型满足io.Reader接口,可以从gzip格式压缩文件读取并解压数据。
一般,一个gzip文件可以是多个gzip文件的串联,每一个都有自己的头域。从Reader读取数据会返回串联的每个文件的解压数据,但只有第一个文件的头域被记录在Reader的Header字段里。
gzip文件会保存未压缩数据的长度与校验和。当读取到未压缩数据的结尾时,如果数据的长度或者校验和不正确,Reader会返回ErrCheckSum。因此,调用者应该将Read方法返回的数据视为暂定的,直到他们在数据结尾获得了一个io.EOF。
func NewReader
func NewReader(r io.Reader) (*Reader, error)
NewReader返回一个从r读取并解压数据的*Reader。其实现会缓冲输入流的数据,并可能从r中读取比需要的更多的数据。调用者有责任在读取完毕后调用返回值的Close方法。
func (*Reader) Reset
func (z *Reader) Reset(r io.Reader) error
Reset将z重置,丢弃当前的读取状态,并将下层读取目标设为r。效果上等价于将z设为使用r重新调用NewReader返回的Reader。这让我们可以重用z而不是再申请一个新的。(因此效率更高)
func (*Reader) Read
func (z *Reader) Read(p []byte) (n int, err error)
func (*Reader) Close
func (z *Reader) Close() error
调用Close会关闭z,但不会关闭下层io.Reader接口。
func main() {
// 压缩
tarFile := "C:/Users/Administrator/Downloads/test001/demo.tar.gz"
dest := "C:/Users/Administrator/Downloads/test001/"
srcFile, err := os.Open(tarFile)
if err != nil {
fmt.Println(err)
return
}
defer srcFile.Close()
gr, err := gzip.NewReader(srcFile)
if err != nil {
fmt.Println(err)
return
}
defer gr.Close()
tr := tar.NewReader(gr)
for {
hdr, err := tr.Next()
if err != nil {
if err == io.EOF {
break
} else {
fmt.Println(err)
return
}
}
filename := dest + hdr.Name
err = os.MkdirAll(string([]rune(filename)[0:strings.LastIndex(filename, "/")]), 0755)
if err != nil {
fmt.Println(err)
return
}
file, _ := os.Create(filename)
io.Copy(file, tr)
}
}
解压文件 tar.gz,先解压缩gzip,再解tar包
type Writer
type Writer struct {
Header // written at first call to Write, Flush, or Close
w io.Writer
level int
wroteHeader bool
compressor *flate.Writer
digest uint32 // CRC-32, IEEE polynomial (section 8)
size uint32 // Uncompressed size (section 2.3.1)
closed bool
buf [10]byte
err error
}
Writer满足io.WriteCloser接口。它会将提供给它的数据压缩后写入下层io.Writer接口。
func NewWriter
func NewWriter(w io.Writer) *Writer
NewWriter创建并返回一个Writer。写入返回值的数据都会在压缩后写入w。调用者有责任在结束写入后调用返回值的Close方法。因为写入的数据可能保存在缓冲中没有刷新入下层。
如要设定Writer.Header字段,调用者必须在第一次调用Write方法或者Close方法之前设置。Header字段的Comment和Name字段是go的utf-8字符串,但下层格式要求为NUL中止的ISO 8859-1 (Latin-1)序列。如果这两个字段的字符串包含NUL或非Latin-1字符,将导致Write方法返回错误。
func NewWriterLevel
func NewWriterLevel(w io.Writer, level int) (*Writer, error)
NewWriterLevel类似NewWriter但指定了压缩水平而不是采用默认的DefaultCompression。
参数level可以是DefaultCompression、NoCompression或BestSpeed与BestCompression之间包括二者的任何整数。如果level合法,返回的错误值为nil。
func (*Writer) Reset
func (z *Writer) Reset(w io.Writer)
Reset将z重置,丢弃当前的写入状态,并将下层输出目标设为dst。效果上等价于将w设为使用dst和w的压缩水平重新调用NewWriterLevel返回的*Writer。这让我们可以重用z而不是再申请一个新的。(因此效率更高)
func (*Writer) Write
func (z *Writer) Write(p []byte) (int, error)
Write将p压缩后写入下层io.Writer接口。压缩后的数据不一定会立刻刷新,除非Writer被关闭或者显式的刷新。
func (*Writer) Flush
func (z *Writer) Flush() error
Flush将缓冲中的压缩数据刷新到下层io.Writer接口中。
本方法主要用在传输压缩数据的网络连接中,以保证远端的接收者可以获得足够的数据来重构数据报。Flush会阻塞直到所有缓冲中的数据都写入下层io.Writer接口后才返回。如果下层的io.Writetr接口返回一个错误,Flush也会返回该错误。在zlib包的术语中,Flush方法等价于Z_SYNC_FLUSH。
func (*Writer) Close
func (z *Writer) Close() error
调用Close会关闭z,但不会关闭下层io.Writer接口。
func main() {
// 压缩
dest := "C:/Users/Administrator/Downloads/test001/demo.tar.gz"
d, _ := os.Create(dest)
defer d.Close()
gw := gzip.NewWriter(d)
defer gw.Close()
tw := tar.NewWriter(gw)
defer tw.Close()
file_dirs := []string{"C:/Users/Administrator/Downloads/test001/test01.sh", "C:/Users/Administrator/Downloads/test001/test02.sh"}
var files []*os.File
for _, dir := range file_dirs {
file, _ := os.Open(dir)
files = append(files, file)
}
for _, file := range files {
info, err := file.Stat()
if err != nil {
fmt.Println(err)
return
}
header, err := tar.FileInfoHeader(info, "")
if err != nil {
fmt.Println(err)
return
}
err = tw.WriteHeader(header)
if err != nil {
fmt.Println(err)
return
}
_, err = io.Copy(tw, file)
file.Close()
if err != nil {
fmt.Println(err)
return
}
}
}
压缩文件 tar与gzip结合,,再打tar包,再压缩
bzip2
bzip2包实现bzip2的解压缩。提供了一个对bzip2压缩包进行读取的操作,但是并没有提供进行bzip2压缩操作。
type StructuralError
type StructuralError string
当bzip2数据的语法不合法时,会返回本类型错误。
func (StructuralError) Error
func (s StructuralError) Error() string
func NewReader
func NewReader(r io.Reader) io.Reader
NewReader返回一个从r读取bzip2压缩数据并解压缩后返回给调用者的io.Reader。
func main() {
fz, err := os.Open("test.bz2")
if err != nil {
log.Fatal(err)
}
w := bzip2.NewReader(fz)
buf := make([]byte, 1024 * 100)
for {
n, err := w.Read(buf)
if n == 0 || err != nil {
break
}
fmt.Println(string(buf[:n]))
}
}
lzw
lzw包实现了Lempel-Ziv-Welch数据压缩格式,这是一种T. A. Welch在“A Technique for High-Performance Data Compression”一文(Computer, 17(6) (June 1984), pp 8-19)提出的一种压缩格式。
本包实现了用于GIF、TIFF、PDF文件的lzw压缩格式,这是一种最长达到12位的变长码,头两个非字面码为clear和EOF码。
type Order
type Order int
Order指定一个lzw数据流的位顺序。
const (
// LSB表示最小权重位在前,用在GIF文件格式
LSB Order = iota
// MSB表示最大权重位在前,用在TIFF和PDF文件格式
MSB
)
func NewReader
func NewReader(r io.Reader, order Order, litWidth int) io.ReadCloser
创建一个io.ReadCloser,它从r读取并解压数据。调用者有责任在结束读取后调用返回值的Close方法;litWidth指定字面码的位数,必须在[2,8]范围内,一般为8。
func NewWriter
func NewWriter(w io.Writer, order Order, litWidth int) io.WriteCloser
创建一个io.WriteCloser,它将数据压缩后写入w。调用者有责任在结束写入后调用返回值的Close方法;litWidth指定字面码的位数,必须在[2,8]范围内,一般为8。
zlib
zlib包实现了对zlib格式压缩数据的读写,参见RFC 1950。
本包的实现提供了在读取时解压和写入时压缩的滤镜。
Constants
const (
NoCompression = flate.NoCompression
BestSpeed = flate.BestSpeed
BestCompression = flate.BestCompression
DefaultCompression = flate.DefaultCompression
)
这些常量都是拷贝自flate包,因此导入"compress/zlib"后,就不必再导入"compress/flate"了。
Variables
var (
// 当读取的zlib数据的校验和错误时,会返回ErrChecksum
ErrChecksum = errors.New("zlib: invalid checksum")
// 当读取的zlib数据的目录错误时,会返回ErrDictionary
ErrDictionary = errors.New("zlib: invalid dictionary")
// 当读取的zlib数据的头域错误时,会返回ErrHeader
ErrHeader = errors.New("zlib: invalid header")
)
func NewReader
func NewReader(r io.Reader) (io.ReadCloser, error)
NewReader返回一个从r读取并解压数据的io.ReadCloser。其实现会缓冲输入流的数据,并可能从r中读取比需要的更多的数据。调用者有责任在读取完毕后调用返回值的Close方法。
func NewReaderDict
func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, error)
NewReaderDict类似NewReader,但会使用预设的字典初始化返回的Reader。
如果压缩数据没有采用字典,本函数会忽略该参数。
type Writer
type Writer struct {
w io.Writer
level int
dict []byte
compressor *flate.Writer
digest hash.Hash32
err error
scratch [4]byte
wroteHeader bool
}
Writer将提供给它的数据压缩后写入下层io.Writer接口。
func NewWriter
func NewWriter(w io.Writer) *Writer
NewWriter创建并返回一个Writer。写入返回值的数据都会在压缩后写入w。
调用者有责任在结束写入后调用返回值的Close方法。因为写入的数据可能保存在缓冲中没有刷新入下层。
Example
func NewWriterLevel
func NewWriterLevel(w io.Writer, level int) (*Writer, error)
NewWriterLevel类似NewWriter但指定了压缩水平而不是采用默认的DefaultCompression。
参数level可以是DefaultCompression、NoCompression或BestSpeed与BestCompression之间包括二者的任何整数。如果level合法,返回的错误值为nil。
func NewWriterLevelDict
func NewWriterLevelDict(w io.Writer, level int, dict []byte) (*Writer, error)
NewWriterLevelDict类似NewWriterLevel但还指定了用于压缩的字典。dict参数可以为nil;否则,在返回的Writer关闭之前,其内容不可被修改。
func (*Writer) Reset
func (z *Writer) Reset(w io.Writer)
Reset将w重置,丢弃当前的写入状态,并将下层输出目标设为dst。效果上等价于将w设为使用dst和w的压缩水平、字典重新调用NewWriterLevel或NewWriterLevelDict返回的*Writer。
func (*Writer) Write
func (z *Writer) Write(p []byte) (n int, err error)
Write将p压缩后写入下层io.Writer接口。压缩后的数据不一定会立刻刷新,除非Writer被关闭或者显式的刷新。
func (*Writer) Flush
func (z *Writer) Flush() error
Flush将缓冲中的压缩数据刷新到下层io.Writer接口中。
func (*Writer) Close
func (z *Writer) Close() error
调用Close会刷新缓冲并关闭w,但不会关闭下层io.Writer接口。
func main() {
// 压缩
buff := []byte{120, 156, 202, 72, 205, 201, 201, 215, 81, 40, 207,
47, 202, 73, 225, 2, 4, 0, 0, 255, 255, 33, 231, 4, 147}
b := bytes.NewReader(buff)
r, err := zlib.NewReader(b)
if err != nil {
panic(err)
}
io.Copy(os.Stdout, r)
r.Close()
var in bytes.Buffer
w := zlib.NewWriter(&in)
w.Write([]byte("hello, world\n"))
w.Close()
zib := in.Bytes()
fmt.Println(zib)
bb := bytes.NewReader(zib)
var out bytes.Buffer
r, _ = zlib.NewReader(bb)
io.Copy(&out, r)
fmt.Println(out.Bytes())
}