| // 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 gzip_test | |
| import ( | |
| "bytes" | |
| "compress/gzip" | |
| "fmt" | |
| "io" | |
| "log" | |
| "net/http" | |
| "net/http/httptest" | |
| "os" | |
| "strings" | |
| "time" | |
| ) | |
| func Example_writerReader() { | |
| var buf bytes.Buffer | |
| zw := gzip.NewWriter(&buf) | |
| // Setting the Header fields is optional. | |
| zw.Name = "a-new-hope.txt" | |
| zw.Comment = "an epic space opera by George Lucas" | |
| zw.ModTime = time.Date(1977, time.May, 25, 0, 0, 0, 0, time.UTC) | |
| _, err := zw.Write([]byte("A long time ago in a galaxy far, far away...")) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| if err := zw.Close(); err != nil { | |
| log.Fatal(err) | |
| } | |
| zr, err := gzip.NewReader(&buf) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| fmt.Printf("Name: %s\nComment: %s\nModTime: %s\n\n", zr.Name, zr.Comment, zr.ModTime.UTC()) | |
| if _, err := io.Copy(os.Stdout, zr); err != nil { | |
| log.Fatal(err) | |
| } | |
| if err := zr.Close(); err != nil { | |
| log.Fatal(err) | |
| } | |
| // Output: | |
| // Name: a-new-hope.txt | |
| // Comment: an epic space opera by George Lucas | |
| // ModTime: 1977-05-25 00:00:00 +0000 UTC | |
| // | |
| // A long time ago in a galaxy far, far away... | |
| } | |
| func ExampleReader_Multistream() { | |
| var buf bytes.Buffer | |
| zw := gzip.NewWriter(&buf) | |
| var files = []struct { | |
| name string | |
| comment string | |
| modTime time.Time | |
| data string | |
| }{ | |
| {"file-1.txt", "file-header-1", time.Date(2006, time.February, 1, 3, 4, 5, 0, time.UTC), "Hello Gophers - 1"}, | |
| {"file-2.txt", "file-header-2", time.Date(2007, time.March, 2, 4, 5, 6, 1, time.UTC), "Hello Gophers - 2"}, | |
| } | |
| for _, file := range files { | |
| zw.Name = file.name | |
| zw.Comment = file.comment | |
| zw.ModTime = file.modTime | |
| if _, err := zw.Write([]byte(file.data)); err != nil { | |
| log.Fatal(err) | |
| } | |
| if err := zw.Close(); err != nil { | |
| log.Fatal(err) | |
| } | |
| zw.Reset(&buf) | |
| } | |
| zr, err := gzip.NewReader(&buf) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| for { | |
| zr.Multistream(false) | |
| fmt.Printf("Name: %s\nComment: %s\nModTime: %s\n\n", zr.Name, zr.Comment, zr.ModTime.UTC()) | |
| if _, err := io.Copy(os.Stdout, zr); err != nil { | |
| log.Fatal(err) | |
| } | |
| fmt.Print("\n\n") | |
| err = zr.Reset(&buf) | |
| if err == io.EOF { | |
| break | |
| } | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| } | |
| if err := zr.Close(); err != nil { | |
| log.Fatal(err) | |
| } | |
| // Output: | |
| // Name: file-1.txt | |
| // Comment: file-header-1 | |
| // ModTime: 2006-02-01 03:04:05 +0000 UTC | |
| // | |
| // Hello Gophers - 1 | |
| // | |
| // Name: file-2.txt | |
| // Comment: file-header-2 | |
| // ModTime: 2007-03-02 04:05:06 +0000 UTC | |
| // | |
| // Hello Gophers - 2 | |
| } | |
| func Example_compressingReader() { | |
| // This is an example of writing a compressing reader. | |
| // This can be useful for an HTTP client body, as shown. | |
| const testdata = "the data to be compressed" | |
| // This HTTP handler is just for testing purposes. | |
| handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { | |
| zr, err := gzip.NewReader(req.Body) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| // Just output the data for the example. | |
| if _, err := io.Copy(os.Stdout, zr); err != nil { | |
| log.Fatal(err) | |
| } | |
| }) | |
| ts := httptest.NewServer(handler) | |
| defer ts.Close() | |
| // The remainder is the example code. | |
| // The data we want to compress, as an io.Reader | |
| dataReader := strings.NewReader(testdata) | |
| // bodyReader is the body of the HTTP request, as an io.Reader. | |
| // httpWriter is the body of the HTTP request, as an io.Writer. | |
| bodyReader, httpWriter := io.Pipe() | |
| // Make sure that bodyReader is always closed, so that the | |
| // goroutine below will always exit. | |
| defer bodyReader.Close() | |
| // gzipWriter compresses data to httpWriter. | |
| gzipWriter := gzip.NewWriter(httpWriter) | |
| // errch collects any errors from the writing goroutine. | |
| errch := make(chan error, 1) | |
| go func() { | |
| defer close(errch) | |
| sentErr := false | |
| sendErr := func(err error) { | |
| if !sentErr { | |
| errch <- err | |
| sentErr = true | |
| } | |
| } | |
| // Copy our data to gzipWriter, which compresses it to | |
| // gzipWriter, which feeds it to bodyReader. | |
| if _, err := io.Copy(gzipWriter, dataReader); err != nil && err != io.ErrClosedPipe { | |
| sendErr(err) | |
| } | |
| if err := gzipWriter.Close(); err != nil && err != io.ErrClosedPipe { | |
| sendErr(err) | |
| } | |
| if err := httpWriter.Close(); err != nil && err != io.ErrClosedPipe { | |
| sendErr(err) | |
| } | |
| }() | |
| // Send an HTTP request to the test server. | |
| req, err := http.NewRequest("PUT", ts.URL, bodyReader) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| // Note that passing req to http.Client.Do promises that it | |
| // will close the body, in this case bodyReader. | |
| resp, err := ts.Client().Do(req) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| // Check whether there was an error compressing the data. | |
| if err := <-errch; err != nil { | |
| log.Fatal(err) | |
| } | |
| // For this example we don't care about the response. | |
| resp.Body.Close() | |
| // Output: the data to be compressed | |
| } |