go
40 lines · 5 steps
Gzip round-trip compression in Go
A pair of functions that compress bytes into a gzip stream and read them back out again.
Explained by
highlit
1package archive
2
3import (
4 "bytes"
5 "compress/gzip"
6 "fmt"
7 "io"
8)
9
10func Compress(data []byte, name string) ([]byte, error) {
11 var buf bytes.Buffer
12 zw, err := gzip.NewWriterLevel(&buf, gzip.BestCompression)
13 if err != nil {
14 return nil, fmt.Errorf("init gzip writer: %w", err)
15 }
16 zw.Name = name
17
18 if _, err := zw.Write(data); err != nil {
19 zw.Close()
20 return nil, fmt.Errorf("write payload: %w", err)
21 }
22 if err := zw.Close(); err != nil {
23 return nil, fmt.Errorf("flush gzip stream: %w", err)
24 }
25 return buf.Bytes(), nil
26}
27
28func Decompress(gzipped []byte) ([]byte, error) {
29 zr, err := gzip.NewReader(bytes.NewReader(gzipped))
30 if err != nil {
31 return nil, fmt.Errorf("open gzip stream: %w", err)
32 }
33 defer zr.Close()
34
35 out, err := io.ReadAll(zr)
36 if err != nil {
37 return nil, fmt.Errorf("read %q: %w", zr.Name, err)
38 }
39 return out, nil
40}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Wrapping a bytes.Buffer with a gzip writer lets you build a compressed blob entirely in memory.
- 2The gzip Close call flushes trailing data, so its error must be checked rather than deferred and ignored.
- 3Wrapping errors with %w preserves the underlying cause while adding context about which stage failed.
Related explainers
ruby
class Order class InvalidTransition < StandardError; end TRANSITIONS = {
A state machine for order transitions in Ruby
state-machine
data-driven
error-handling
Intermediate
8 steps
go
package theme import ( "fmt"
Per-tenant HTML templates with Gin's renderer
multi-tenancy
concurrency
html-templates
Advanced
8 steps
go
package auth import ( "net/http"
Setting and reading secure session cookies in Go
cookies
session-management
security
Intermediate
6 steps
rust
use std::cmp::Ordering; use std::str::FromStr; #[derive(Debug, Clone, PartialEq, Eq)]
Parsing and ordering semantic versions in Rust
parsing
trait-implementation
ordering
Intermediate
8 steps
javascript
'use client'; import { useEffect } from 'react'; import * as Sentry from '@sentry/nextjs';
How a Next.js error boundary recovers
error-boundary
error-handling
observability
Intermediate
8 steps
ruby
class Registration < ApplicationRecord belongs_to :event validates :email, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }
Validating registrations in Rails
validations
i18n
error-handling
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/gzip-round-trip-compression-in-go-explained-go-6e7e/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.