压缩比=原始文件大小÷压缩后文件大小;需在gzip.writer.close()后用os.stat获取准确大小,内存数据用len(data)和buf.len()计算,压缩级别1–9显著影响比值与耗时。

压缩比怎么算:直接用 os.Stat 拿原始和压缩后大小
压缩比不是靠 guess,而是两个数字相除:原始文件大小 ÷ 压缩后文件大小。Go 里没有内置“压缩比函数”,但 os.Stat 能立刻拿到两个 Size() 值,一除就完事。
- 必须等
gzip.Writer.Close()执行完再调用os.Stat,否则 .gz 文件可能还没写满,大小不准 - 别用
io.Copy后立刻Stat目标文件——gzip.Writer的缓冲区还在内存里,没刷到磁盘 - 如果源文件是内存数据(比如
[]byte),原始大小就是len(data);压缩后大小取自buf.Len()(bytes.Buffer)
gzip.NewWriterLevel 对压缩比的影响很实在
默认压缩级别是 gzip.DefaultCompression(值为 6),但改它会明显改变结果。级别从 1(gzip.BestSpeed)到 9(gzip.BestCompression),压缩比和耗时都线性变化。
- 级别 1:压缩比可能只有 1.2:1,但速度快;适合日志实时落盘场景
- 级别 6:平衡点,约 2.8–3.2:1,大多数文件的推荐起点
- 级别 9:对文本类数据可能达 3.5:1+,但 CPU 时间可能翻倍,小文件不值得
- 注意:二进制文件(如图片、已压缩的 PDF)再压基本没收益,甚至可能变大
别把 archive/zip 和 compress/gzip 的压缩比混着比
gzip 压的是单个流,zip 是归档格式,自带文件头、目录结构、甚至可选加密——它内部用的也是 DEFLATE,但额外开销会让“压缩比”数值虚高或偏低。
- 拿
input.txt压成input.txt.gzvsarchive.zip包一个文件:后者多出几百字节头信息,小文件下压缩比反而更差 - 多文件场景下,
tar.gz是合理组合:tar打包(无压缩)+gzip压缩整个流,此时压缩比反映的是纯内容压缩能力 - 实测中,同内容下
gzip比zip的压缩比高 0.1–0.3:1,但差距随文件增大而收窄
大文件压缩比计算要防缓存干扰
超过几百 MB 的文件,os.Stat 返回的 Size() 是准确的,但你得确认自己没被 OS 缓存或写入延迟骗到。
- Linux/macOS 下,
sync系统调用不是必须的,但gzip.Writer.Close()内部已调用Flush()+WriteHeader(),只要没 panic 就已落盘 - 真正容易错的是并发压多个文件时共享了同一个
bytes.Buffer或没重置,导致buf.Len()累加 - 如果用
io.CopyBuffer配合自定义 buffer,记得 buffer 大小不影响压缩比,只影响内存占用和 syscall 频次
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











