用 gzip.writer 写入压缩内容需先创建并包装目标文件,再写数据,最后调用 close() 刷出压缩尾部;漏掉 close 会导致解压失败;支持多次 write,但不可随机写。

用 gzip.Writer 写入压缩内容,不是先写文件再压缩
Go 里没有“把一个已存在的文件直接 gzip 压缩成另一个文件”的单函数操作。必须手动创建 gzip.Writer,往它里面写原始数据,它会边写边压缩并输出到目标 io.Writer(比如文件)。常见错误是试图对普通 *os.File 直接调用 Write,结果写进去的是明文——忘了套一层压缩器。
关键点:
-
gzip.Writer包装的是输出目标,不是输入源 - 必须调用
Close()才能刷出最终压缩头和校验信息,否则解压失败或报invalid checksum - 写入前不用手动设置文件扩展名,但建议按惯例命名为
.gz
完整写入流程:打开文件 → 创建 gzip.Writer → 写数据 → 关闭
下面是最小可靠写法:
file, err := os.Create("data.txt.gz")
if err != nil {
log.Fatal(err)
}
defer file.Close()
gz := gzip.NewWriter(file)
defer gz.Close() // 注意:这里 close 的是 gzip.Writer,不是 file
_, err = gz.Write([]byte("hello world\n"))
if err != nil {
log.Fatal(err)
}
// gz.Close() 会 flush 压缩流并写入尾部信息
漏掉 gz.Close() 是高频问题——程序看似运行成功,但生成的 .gz 文件无法被 gunzip 或 zcat 正确识别。
gzip.Writer 的 Level 参数影响压缩率和速度
默认使用 gzip.DefaultCompression(值为 6),但你可以显式控制:
-
gzip.NoCompression:不压缩,仅打包(快,体积大) -
gzip.BestSpeed:最快压缩(-1,实际等价于1) -
gzip.BestCompression:最高压缩率(-5,实际等价于9) - 传整数
1–9也可,Go 内部会映射
示例(高压缩):
gz, err := gzip.NewWriterLevel(file, gzip.BestCompression)
if err != nil {
log.Fatal(err)
}
注意:NewWriterLevel 可能返回 error(比如传了非法 level),而 NewWriter 不会。
写入多段内容?直接连续 Write 即可,无需额外处理
gzip.Writer 支持多次 Write 调用,内部自动拼接并压缩。适合日志追加、分块上传等场景:
gz.Write([]byte("first line\n"))
gz.Write([]byte("second line\n"))
gz.Write([]byte("third line\n"))
gz.Close() // 一次 close 就够了
不要为每段内容新建一个 gzip.Writer——那样会生成多个独立 gzip 流,解压时只能拿到第一段。
另外,gzip.Writer 不支持随机写或 seek,所有写入必须顺序进行。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











