go标准库compress/gzip是生产环境首选,需将字符串转[]byte、调用close()、小数据用64kb缓冲、磁盘写入套bufio.writer,base64编码确保json兼容。

golang 中用 gzip 压缩字节流最直接
Go 标准库的 compress/gzip 是生产环境最常用、最稳妥的选择。它不依赖外部工具,压缩比和速度平衡,且与 Linux/HTTP 等生态兼容性好。
关键点是:别直接压缩原始字符串,先转成 []byte;压缩后得到的是二进制数据,存储或传输前需确认目标系统能处理 raw bytes(比如写文件没问题,但存 JSON 字段需 base64 编码)。
-
gzip.Writer必须调用Close(),否则末尾元数据丢失,解压会报invalid header - 压缩级别用
gzip.BestSpeed或gzip.BestCompression,别传整数 ——gzip.DefaultCompression已足够多数场景 - 如果反复压缩小数据(
buf := &bytes.Buffer{}
gz := gzip.NewWriter(buf)
gz.Write([]byte("your data here"))
gz.Close() // 必须!
compressed := buf.Bytes()
存数据库前要不要 base64 编码 gzip 结果
要看字段类型。MySQL 的 BLOB、PostgreSQL 的 BYTEA 可直接存 []byte;但如果是 TEXT 字段或要嵌入 JSON,就必须编码。
base64 是安全选择,但体积膨胀约 33%;hex 编码更冗余(100% 膨胀),不推荐。若用 ORM(如 GORM),注意它对 []byte 的默认处理 —— 某些版本会自动 base64,某些则原样塞,得看文档或实测。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 存
BLOB:直接db.Exec("INSERT ...", compressed) - 存
TEXT或 JSON:base64.StdEncoding.EncodeToString(compressed) - 解压时先判断是否 base64 编码 —— 看开头是不是
"eyJ"或长度是否 4 的倍数且含'+'/'/',再决定是否base64.StdEncoding.DecodeString()
用 zlib 还是 gzip?协议兼容性决定选型
二者算法相同(DEFLATE),区别在封装格式:gzip 有魔数 1f 8b,zlib 是 78 01 / 78 9c。HTTP 响应头 Content-Encoding: gzip 明确要求 gzip 格式;而 Go 的 compress/zlib 包常用于与 Python 的 zlib.compress()(默认 zlib 格式)互通。
- 和浏览器、Nginx、curl 交互 → 用
compress/gzip - 和 Python
zlib模块对接 → 用compress/zlib,且注意 Python 默认不加 header,可能需设zlib.compress(data, wbits=-zlib.MAX_WBITS) - 不要混用:用
gzip.Reader解zlib数据会报invalid header
大文件分块压缩避免内存爆掉
一次性读整个文件进内存再压缩,遇到几百 MB 文件就容易 OOM。正确做法是流式处理:开一个固定大小 buffer(如 64KB),io.CopyBuffer 配合 gzip.Writer。
尤其注意:别用 os.ReadFile + gzip.NewWriter(bytes.Buffer) 处理大文件,这是新手高频翻车点。
- 源文件 >10MB 就该走流式
- buffer 太小(1MB)浪费内存,64KB 是经验值
- 压缩后写磁盘时也建议用
bufio.Writer包一层,减少 write 系统调用次数
src, _ := os.Open("big.log")
dst, _ := os.Create("big.log.gz")
gz := gzip.NewWriter(dst)
defer gz.Close()
io.CopyBuffer(gz, src, make([]byte, 64*1024))
实际用的时候,最容易漏的是 Close() 和 base64 编码判断逻辑 —— 这俩问题在线上往往表现为“有时解压失败”或“存进去的数据显示为空”,排查起来特别绕。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










