?
本文檔使用 php中文網(wǎng)手冊 發(fā)布
import "compress/flate"
概述
參數(shù)
示例
Package flate 實現(xiàn)了 RFC 1951 中描述的 DEFLATE 壓縮數(shù)據(jù)格式. gzip 和 zlib 包實現(xiàn)了對基于 DEFLATE 的文件格式的訪問。
預(yù)設(shè)詞典可用于提高壓縮比。使用字典的缺點是壓縮器和解壓縮器必須事先同意使用什么字典。
package mainimport ("bytes""compress/flate""fmt""io""log""os""strings")func main() {// 字典是一串字節(jié)。 壓縮一些輸入數(shù)據(jù)時,// 壓縮器將嘗試用找到的匹配替換子串// 在庫里。因此,庫應(yīng)該只包含子字符串// 預(yù)計會在實際的數(shù)據(jù)流中找到。const dict = `<?xml version="1.0"?>` + `<book>` + `<data>` + `<meta name="` + `" content="`// 要壓縮的數(shù)據(jù)應(yīng)該(但不是必需的)包含頻繁的數(shù)據(jù)// 子字符串,匹配字典中的字符串。const data = `<?xml version="1.0"?> <book> <meta name="title" content="The Go Programming Language"/> <meta name="authors" content="Alan Donovan and Brian Kernighan"/> <meta name="published" content="2015-10-26"/> <meta name="isbn" content="978-0134190440"/> <data>...</data> </book> `var b bytes.Buffer// 使用特制字典壓縮數(shù)據(jù)。 zw, err := flate.NewWriterDict(&b, flate.DefaultCompression, []byte(dict))if err != nil { log.Fatal(err)}if _, err := io.Copy(zw, strings.NewReader(data)); err != nil { log.Fatal(err)}if err := zw.Close(); err != nil { log.Fatal(err)}// 解壓縮器必須使用與壓縮器相同的字典。// 否則,輸入可能顯示為損壞。 fmt.Println("Decompressed output using the dictionary:") zr := flate.NewReaderDict(bytes.NewReader(b.Bytes()), []byte(dict))if _, err := io.Copy(os.Stdout, zr); err != nil { log.Fatal(err)}if err := zr.Close(); err != nil { log.Fatal(err)} fmt.Println()// 使用'#'替代字典中的所有字節(jié)以直觀地顯示// 演示使用預(yù)設(shè)詞典的大致效果。 fmt.Println("Substrings matched by the dictionary are marked with #:") hashDict := []byte(dict)for i := range hashDict { hashDict[i] = '#'} zr = flate.NewReaderDict(&b, hashDict)if _, err := io.Copy(os.Stdout, zr); err != nil { log.Fatal(err)}if err := zr.Close(); err != nil { log.Fatal(err)}}
在性能至關(guān)重要的應(yīng)用中,Reset 可以用來丟棄當(dāng)前的壓縮器或解壓縮器狀態(tài),并利用先前分配的內(nèi)存快速重新初始化它們。
package mainimport ("bytes""compress/flate""io""log""os""strings")func main() { proverbs := []string{"Don't communicate by sharing memory, share memory by communicating.\n","Concurrency is not parallelism.\n","The bigger the interface, the weaker the abstraction.\n","Documentation is for users.\n",}var r strings.Readervar b bytes.Buffer buf := make([]byte, 32<<10) zw, err := flate.NewWriter(nil, flate.DefaultCompression)if err != nil { log.Fatal(err)} zr := flate.NewReader(nil)for _, s := range proverbs { r.Reset(s) b.Reset()// 重置壓縮器并從某些輸入流編碼。 zw.Reset(&b)if _, err := io.CopyBuffer(zw, &r, buf); err != nil { log.Fatal(err)}if err := zw.Close(); err != nil { log.Fatal(err)}// 重置解壓縮器并解碼為某個輸出流。if err := zr.(flate.Resetter).Reset(&b, nil); err != nil { log.Fatal(err)}if _, err := io.CopyBuffer(os.Stdout, zr, buf); err != nil { log.Fatal(err)}if err := zr.Close(); err != nil { log.Fatal(err)}}}
DEFLATE 適用于通過網(wǎng)絡(luò)傳輸壓縮數(shù)據(jù)。
package mainimport ("compress/flate""fmt""io""log""strings""sync")func main() {var wg sync.WaitGroup defer wg.Wait()// 使用io.Pipe來模擬網(wǎng)絡(luò)連接。// 真正的網(wǎng)絡(luò)應(yīng)用程序應(yīng)小心妥善關(guān)閉// 底層連接。 rp, wp := io.Pipe()// 啟動一個 goroutine 來充當(dāng)發(fā)射器。 wg.Add(1) go func() { defer wg.Done() zw, err := flate.NewWriter(wp, flate.BestSpeed)if err != nil { log.Fatal(err)} b := make([]byte, 256)for _, m := range strings.Fields("A long time ago in a galaxy far, far away...") {// 我們使用一個簡單的成幀格式,其中第一個字節(jié)是// 消息長度,跟隨消息本身。 b[0] = uint8(copy(b[1:], m))if _, err := zw.Write(b[:1+len(m)]); err != nil { log.Fatal(err)}// 刷新確保接收器可以讀取迄今為止發(fā)送的所有數(shù)據(jù)。if err := zw.Flush(); err != nil { log.Fatal(err)}}if err := zw.Close(); err != nil { log.Fatal(err)}}()// 開始一個 goroutine 充當(dāng)接收者。 wg.Add(1) go func() { defer wg.Done() zr := flate.NewReader(rp) b := make([]byte, 256)for {// 閱讀消息長度。// 這是保證返回每個相應(yīng)的// (Flush)沖洗并(Close)關(guān)閉發(fā)射器側(cè)。if _, err := io.ReadFull(zr, b[:1]); err != nil {if err == io.EOF {break // 發(fā)射機關(guān)閉了流} log.Fatal(err)}// 閱讀郵件內(nèi)容。 n := int(b[0])if _, err := io.ReadFull(zr, b[:n]); err != nil { log.Fatal(err)} fmt.Printf("Received %d bytes: %s\n", n, b[:n])} fmt.Println()if err := zr.Close(); err != nil { log.Fatal(err)}}()}
Constants(常量)
func NewReader(r io.Reader) io.ReadCloser
func NewReaderDict(r io.Reader, dict []byte) io.ReadCloser
type CorruptInputError
func (e CorruptInputError) Error() string
type InternalError
func (e InternalError) Error() string
type ReadError
func (e *ReadError) Error() string
type Reader
type Resetter
type WriteError
func (e *WriteError) Error() string
type Writer
func NewWriter(w io.Writer, level int) (*Writer, error)
func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error)
func (w *Writer) Close() error
func (w *Writer) Flush() error
func (w *Writer) Reset(dst io.Writer)
func (w *Writer) Write(data []byte) (n int, err error)
Package (Dictionary) Package (Reset) Package (Synchronization)
deflate.go deflatefast.go dict_decoder.go huffman_bit_writer.go huffman_code.go inflate.go token.go
const ( NoCompression = 0 BestSpeed = 1 BestCompression = 9 DefaultCompression = -1 // HuffmanOnly 禁用 Lempel-Ziv 匹配搜索并僅執(zhí)行 Huffman // 熵編碼。 此模式在壓縮具有的數(shù)據(jù)時非常有用 // 已經(jīng)使用LZ樣式算法壓縮(例如Snappy或LZ4) // 缺少熵編碼器。 當(dāng)壓縮增益達到時 // 輸入流中的某些字節(jié)比其他字節(jié)更頻繁地出現(xiàn)。 // // 請注意,HuffmanOnly會生成一個壓縮輸出 // 符合RFC 1951。 也就是說,任何有效的DEFLATE解壓縮器都會 // 繼續(xù)能夠解壓縮此輸出。 HuffmanOnly = -2)
func NewReader(r io.Reader) io.ReadCloser
NewReader 返回一個新的 ReadCloser,可用于讀取r的未壓縮版本。如果r不執(zhí)行 io.ByteReader,則解壓縮程序可能從r讀取比所需更多的數(shù)據(jù)。完成閱讀時,調(diào)用者有責(zé)任在ReadCloser上調(diào)用 Close。
NewReader 返回的 ReadCloser 也實現(xiàn)了Resetter。
func NewReaderDict(r io.Reader, dict []byte) io.ReadCloser
NewReaderDict 與 NewReader類似,但用預(yù)設(shè)字典初始化閱讀器。返回的 Reader 的行為就像未壓縮的數(shù)據(jù)流以給定的字典開始,該字典已經(jīng)被讀取。NewReaderDict 通常用于讀取由NewWriterDict 壓縮的數(shù)據(jù)。
NewReader 返回的 ReadCloser 也實現(xiàn)了 Resetter。
CorruptInputError 報告給定偏移處存在損壞的輸入。
type CorruptInputError int64
func (e CorruptInputError) Error() string
InternalError 在 flate 代碼本身中報告錯誤。
type InternalError string
func (e InternalError) Error() string
ReadError 報告讀取輸入時遇到的錯誤。
已棄用:不再返回。
type ReadError struct { Offset int64 // 發(fā)生錯誤的字節(jié)偏移量 Err error // 底層Read返回的錯誤
func (e *ReadError) Error() string
NewReader 所需的實際讀取界面。如果傳入的 io.Reader 不具有ReadByte,則 NewReader 將引入它自己的緩沖區(qū)。
type Reader interface { io.Reader io.ByteReader}
Resetter 重置由 NewReader 或 NewReaderDict 返回的 ReadCloser 以切換到新的底層 Reader。這允許重新使用 ReadCloser 而不是分配新的。
type Resetter interface { // 重置會丟棄所有緩沖的數(shù)據(jù)并重置Resetter,就像它一樣 // 最初用給定的讀者初始化。 Reset(r io.Reader, dict []byte) error}
WriteError 報告寫入輸出時遇到的錯誤。
已棄用:不再返回。
type WriteError struct { Offset int64 // 發(fā)生錯誤的字節(jié)偏移量 Err error // 底層Write返回的錯誤}
func (e *WriteError) Error() string
Writer 將寫入數(shù)據(jù)的數(shù)據(jù)寫入底層寫入器(請參閱NewWriter)。
type Writer struct { // 包含已過濾或未導(dǎo)出的字段}
func NewWriter(w io.Writer, level int) (*Writer, error)
NewWriter 返回一個新的 Writer,壓縮給定級別的數(shù)據(jù)。在zlib之后,級別從 1(BestSpeed)到 9(BestCompression); 較高的水平通常運行較慢但壓縮更多。級別 0(NoCompression)不嘗試任何壓縮; 它只增加必要的DEFLATE成幀。級別-1(DefaultCompression)使用默認(rèn)的壓縮級別。等級-2(HuffmanOnly)僅使用霍夫曼壓縮,為所有類型的輸入提供非??焖俚膲嚎s,但會犧牲相當(dāng)大的壓縮效率。
如果級別在-2,9范圍內(nèi),則返回的錯誤將為零。否則,返回的錯誤將不為零。
func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error)
NewWriterDict 就像 NewWriter,但是用一個預(yù)置字典初始化新的 Writer。返回的 Writer 的行為就好像字典已經(jīng)寫入,而不產(chǎn)生任何壓縮輸出。寫入 w 的壓縮數(shù)據(jù)只能由使用相同字典初始化的 Reader 解壓縮。
func (w *Writer) Close() error
關(guān)閉刷新并關(guān)閉 writer。
func (w *Writer) Flush() error
刷新將任何未決數(shù)據(jù)刷新到底層寫入器。它主要用于壓縮網(wǎng)絡(luò)協(xié)議,以確保遠程讀取器有足夠的數(shù)據(jù)來重建數(shù)據(jù)包。在數(shù)據(jù)寫入之前,刷新不會返回。在沒有待處理數(shù)據(jù)時調(diào)用 Flush 仍然會導(dǎo)致 Writer 發(fā)出至少4個字節(jié)的同步標(biāo)記。如果底層編寫器返回錯誤,F(xiàn)lush 將返回該錯誤。
在 zlib 庫的術(shù)語中,F(xiàn)lush 等價于 Z_SYNC_FLUSH。
func (w *Writer) Reset(dst io.Writer)
重置放棄 writer 的狀態(tài),并使其等同于使用dst和w的級別和字典調(diào)用 NewWriter 或 NewWriterDict 的結(jié)果。
func (w *Writer) Write(data []byte) (n int, err error)
寫入數(shù)據(jù)寫入 w,最終將壓縮形式的數(shù)據(jù)寫入其底層寫入器。