首页 > 后端开发 > Golang > 正文

如何用Golang的compress库处理压缩 gzip/zlib实战案例

P粉602998670
发布: 2025-08-14 19:56:01
原创
1003人浏览过

go语言中compress/gzip和compress/zlib均基于deflate算法,gzip适用于文件和http压缩,因包含头部和校验信息,而zlib更轻量,适合协议传输;通过newwriter压缩数据并需调用close刷新,newreader解压后也需close释放资源;可实现http中间件自动压缩响应体,或读写.gz文件用于日志归档;两者api相似,但封装格式不同,gzip多用于存储,zlib用于体积敏感场景,正确使用可有效减少传输体积,完整掌握后可用于多种实际场景。

如何用Golang的compress库处理压缩 gzip/zlib实战案例

Go语言标准库中的

compress
登录后复制
包提供了对多种压缩格式的支持,其中
gzip
登录后复制
zlib
登录后复制
是最常用的两种。它们都基于 DEFLATE 算法,但在封装格式和用途上略有不同。本文通过几个实用案例,带你掌握如何在实际项目中使用 Golang 的
compress/gzip
登录后复制
compress/zlib
登录后复制
库。


1. 使用
compress/gzip
登录后复制
压缩和解压数据

gzip
登录后复制
常用于 HTTP 响应压缩、文件压缩(如
.gz
登录后复制
文件)等场景。

压缩字符串为 gzip 数据

package main

import (
    "bytes"
    "compress/gzip"
    "fmt"
    "io"
)

func compressGzip(data string) ([]byte, error) {
    var buf bytes.Buffer
    writer := gzip.NewWriter(&buf)
    _, err := io.WriteString(writer, data)
    if err != nil {
        return nil, err
    }
    if err := writer.Close(); err != nil {
        return nil, err
    }
    return buf.Bytes(), nil
}

func main() {
    original := "Hello, this is a test string for gzip compression."
    compressed, err := compressGzip(original)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Original: %d bytes\n", len(original))
    fmt.Printf("Compressed: %d bytes\n", len(compressed))
}
登录后复制

解压 gzip 数据

func decompressGzip(data []byte) (string, error) {
    reader, err := gzip.NewReader(bytes.NewReader(data))
    if err != nil {
        return "", err
    }
    defer reader.Close()
    var buf bytes.Buffer
    _, err = io.Copy(&buf, reader)
    if err != nil {
        return "", err
    }
    return buf.String(), nil
}
登录后复制

main
登录后复制
中调用:

立即学习go语言免费学习笔记(深入)”;

decompressed, err := decompressGzip(compressed)
if err != nil {
    panic(err)
}
fmt.Printf("Decompressed: %s\n", decompressed)
登录后复制
注意:gzip.NewReader 必须调用 Close() 释放内部资源,即使只读取一次。

2. 使用
compress/zlib
登录后复制
进行轻量级压缩

zlib
登录后复制
格式比
gzip
登录后复制
更轻,常用于协议传输、数据库存储等对体积敏感但不需要文件头信息的场景。

AiTxt 文案助手
AiTxt 文案助手

AiTxt 利用 Ai 帮助你生成您想要的一切文案,提升你的工作效率。

AiTxt 文案助手 15
查看详情 AiTxt 文案助手

压缩数据为 zlib 格式

import "compress/zlib"

func compressZlib(data string) ([]byte, error) {
    var buf bytes.Buffer
    writer := zlib.NewWriter(&buf)
    _, err := io.WriteString(writer, data)
    if err != nil {
        return nil, err
    }
    if err := writer.Close(); err != nil {
        return nil, err
    }
    return buf.Bytes(), nil
}
登录后复制

解压 zlib 数据

func decompressZlib(data []byte) (string, error) {
    reader, err := zlib.NewReader(bytes.NewReader(data))
    if err != nil {
        return "", err
    }
    defer reader.Close()
    var buf bytes.Buffer
    _, err = io.Copy(&buf, reader)
    if err != nil {
        return "", err
    }
    return buf.String(), nil
}
登录后复制

用法与

gzip
登录后复制
类似,只是换用了
zlib
登录后复制
包。


3. 实战:HTTP 中间件支持 gzip 压缩响应

在 Web 服务中,我们可以使用

gzip
登录后复制
来压缩响应体,减少传输体积。

package main

import (
    "compress/gzip"
    "net/http"
)

type gzipResponseWriter struct {
    http.ResponseWriter
    *gzip.Writer
}

func (w gzipResponseWriter) Write(data []byte) (int, error) {
    return w.Writer.Write(data)
}

func gzipMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
            next.ServeHTTP(w, r)
            return
        }

        writer := gzip.NewWriter(w)
        defer writer.Close()

        w.Header().Set("Content-Encoding", "gzip")
        w.Header().Set("Vary", "Accept-Encoding")

        gzResp := gzipResponseWriter{ResponseWriter: w, Writer: writer}
        next.ServeHTTP(gzResp, r)
    })
}

func handler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("This is a large response that will be compressed with gzip."))
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", handler)
    http.ListenAndServe(":8080", gzipMiddleware(mux))
}
登录后复制

这个中间件检查客户端是否支持

gzip
登录后复制
,如果支持,则包装
ResponseWriter
登录后复制
并设置编码头。


4. 处理
.gz
登录后复制
文件:读写压缩文件

Go 可以直接读写

.gz
登录后复制
文件,适合处理日志归档等场景。

写入 gzip 文件

import (
    "os"
    "compress/gzip"
)

func writeGzipFile(filename, content string) error {
    file, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer file.Close()

    gz := gzip.NewWriter(file)
    defer gz.Close()

    _, err = gz.Write([]byte(content))
    return err
}
登录后复制

读取 gzip 文件

func readGzipFile(filename string) (string, error) {
    file, err := os.Open(filename)
    if err != nil {
        return "", err
    }
    defer file.Close()

    gz, err := gzip.NewReader(file)
    if err != nil {
        return "", err
    }
    defer gz.Close()

    content, err := io.ReadAll(gz)
    return string(content), err
}
登录后复制

小结关键点

  • gzip
    登录后复制
    zlib
    登录后复制
    都使用
    NewWriter
    登录后复制
    NewReader
    登录后复制
    ,API 高度相似。
  • 压缩后必须调用
    Close()
    登录后复制
    触发 flush,否则数据不完整。
  • gzip.NewReader
    登录后复制
    zlib.NewReader
    登录后复制
    返回的 reader 必须
    Close()
    登录后复制
  • gzip
    登录后复制
    包含文件头和校验和,适合文件存储;
    zlib
    登录后复制
    更紧凑,适合嵌入协议。
  • 在 HTTP 服务中启用压缩可显著减少带宽。

基本上就这些。掌握这几个模式后,你可以灵活应用于日志压缩、API 响应、配置传输等场景。

以上就是如何用Golang的compress库处理压缩 gzip/zlib实战案例的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号