golang example_test 代码
文件路径:/src/compress/flate/example_test.go
/ Copyright 2016 The Go Authors. All rights reserved.
/ Use of this source code is governed by a BSD-style
/ license that can be found in the LICENSE file.
package flate_test
import (
"bytes"
"compress/flate"
"fmt"
"io"
"log"
"os"
"strings"
"sync"
)
/ In performance critical applications, Reset can be used to discard the
/ current compressor or decompressor state and reinitialize them quickly
/ by taking advantage of previously allocated memory.
func Example_reset() {
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.Reader
var 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()
/ Reset the compressor and encode from some input stream.
zw.Reset(&b)
if _, err := io.CopyBuffer(zw, &r, buf); err != nil {
log.Fatal(err)
}
if err := zw.Close(); err != nil {
log.Fatal(err)
}
/ Reset the decompressor and decode to some output stream.
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)
}
}
/ Output:
/ Don't communicate by sharing memory, share memory by communicating.
/ Concurrency is not parallelism.
/ The bigger the interface, the weaker the abstraction.
/ Documentation is for users.
}
/ A preset dictionary can be used to improve the compression ratio.
/ The downside to using a dictionary is that the compressor and decompressor
/ must agree in advance what dictionary to use.
func Example_dictionary() {
/ The dictionary is a string of bytes. When compressing some input data,
/ the compressor will attempt to substitute substrings with matches found
/ in the dictionary. As such, the dictionary should only contain substrings
/ that are expected to be found in the actual data stream.
const dict = `<?xml version="1.0"?>` + `<book>` + `<data>` + `<meta name="` + `" content="`
/ The data to compress should (but is not required to) contain frequent
/ substrings that match those in the dictionary.
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
/ Compress the data using the specially crafted dictionary.
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)
}
/ The decompressor must use the same dictionary as the compressor.
/ Otherwise, the input may appear as corrupted.
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()
/ Substitute all of the bytes in the dictionary with a '#' to visually
/ demonstrate the approximate effectiveness of using a preset dictionary.
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)
}
/ Output:
/ Decompressed output using the dictionary:
/ <?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>
/
/ Substrings matched by the dictionary are marked with #:
/ #####################
/ ######
/ ############title###########The Go Programming Language"/#
/ ############authors###########Alan Donovan and Brian Kernighan"/#
/ ############published###########2015-10-26"/#
/ ############isbn###########978-0134190440"/#
/ ######...</#####
/ </#####
}
/ DEFLATE is suitable for transmitting compressed data across the network.
func Example_synchronization() {
var wg sync.WaitGroup
defer wg.Wait()
/ Use io.Pipe to simulate a network connection.
/ A real network application should take care to properly close the
/ underlying connection.
rp, wp := io.Pipe()
/ Start a goroutine to act as the transmitter.
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...") {
/ We use a simple framing format where the first byte is the
/ message length, followed the message itself.
b[0] = uint8(copy(b[1:], m))
if _, err := zw.Write(b[:1+len(m)]); err != nil {
log.Fatal(err)
}
/ Flush ensures that the receiver can read all data sent so far.
if err := zw.Flush(); err != nil {
log.Fatal(err)
}
}
if err := zw.Close(); err != nil {
log.Fatal(err)
}
}()
/ Start a goroutine to act as the receiver.
wg.Add(1)
go func() {
defer wg.Done()
zr := flate.NewReader(rp)
b := make([]byte, 256)
for {
/ Read the message length.
/ This is guaranteed to return for every corresponding
/ Flush and Close on the transmitter side.
if _, err := io.ReadFull(zr, b[:1]); err != nil {
if err == io.EOF {
break / The transmitter closed the stream
}
log.Fatal(err)
}
/ Read the message content.
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)
}
}()
/ Output:
/ Received 1 bytes: A
/ Received 4 bytes: long
/ Received 4 bytes: time
/ Received 3 bytes: ago
/ Received 2 bytes: in
/ Received 1 bytes: a
/ Received 6 bytes: galaxy
/ Received 4 bytes: far,
/ Received 3 bytes: far
/ Received 7 bytes: away...
}