0

0

如何在Golang中实现文件压缩功能_Golang zip/tar 文件操作示例

P粉602998670

P粉602998670

发布时间:2026-01-08 17:31:58

|

889人浏览过

|

来源于php中文网

原创

Go用archive/zip压缩需手动写入文件头与内容:调用CreateHeader/Create创建条目,再写入数据;路径用/分隔;打包目录要过滤符号链接和隐藏文件;中文名需设header.Flags=1启用UTF-8。

如何在golang中实现文件压缩功能_golang zip/tar 文件操作示例

archive/zip 压缩单个文件时,必须手动写入文件头和内容

Go 标准库不提供“一键压缩”函数,zip.Writer 只负责构建 ZIP 结构,你需要自己调用 writer.CreateHeader()writer.Create() 创建条目,再把源文件内容写进去。漏掉任一环节都会导致 ZIP 文件损坏或解压为空。

  • writer.Create("foo.txt") 返回一个 io.Writer,后续写入的数据会作为该文件内容;适合小文件或内存中生成的内容
  • 压缩已有文件时,更稳妥的方式是:header := &zip.FileHeader{Name: "bar.txt", Method: zip.Deflate}header.SetModTime(time.Now())w, _ := writer.CreateHeader(header)io.Copy(w, srcFile)
  • 注意:ZIP 中路径分隔符必须用 /(即使在 Windows 上),否则部分解压工具无法识别目录结构

打包整个目录时,递归遍历需跳过符号链接和系统隐藏文件

直接 filepath.Walk 会进入符号链接目标、.git 目录、临时文件等,不仅增大 ZIP 体积,还可能触发权限错误或循环引用。必须显式过滤。

  • 检查 os.FileInfo.Mode() & os.ModeSymlink != 0 跳过符号链接
  • 对每个路径用 strings.HasPrefix(fi.Name(), ".") 过滤隐藏文件(如 .DS_Store.gitignore
  • 路径重写要保留相对结构:若从 /tmp/project 开始打包,/tmp/project/src/main.go 应写入 ZIP 的 src/main.go,而非绝对路径
  • strings.TrimPrefix(absPath, baseDir) + strings.ReplaceAll(..., "\\", "/") 统一路径分隔符

archive/tar 不带压缩,但配合 gzipzstd 可实现 .tar.gz / .tar.zst

archive/tar 本身只做归档,不是压缩格式。常见 “tar.gz” 实际是先 tar 再 gzip 流式编码,不能直接用 tar.Writer 写入 *gzip.Writer 就完事——顺序和关闭时机很关键。

360鸿图
360鸿图

360公司推出的AI绘画生成工具

下载
  • 正确链路:file, _ := os.Create("out.tar.gz")gzipWriter := gzip.NewWriter(file)tarWriter := tar.NewWriter(gzipWriter)
  • 写完所有文件后,必须按相反顺序关闭:tarWriter.Close()gzipWriter.Close()file.Close(),否则 gzip 尾部校验数据丢失,解压报 invalid checksum
  • 如果要用 zstd(比 gzip 压缩率更高),替换 gzip.NewWriterzstd.NewWriter(需引入 github.com/klauspost/compress/zstd
  • tar.Header.Size 必须设为真实文件字节数,否则解压时截断或卡住

中文文件名在 ZIP 中乱码,是因为 Go 默认用 UTF-8 编码而多数解压工具认 CP437

ZIP 规范本身不强制字符编码,archive/zipFileHeader.Name 当作原始字节写入。Windows 资源管理器macOS 归档工具默认按 CP437 解析,导致中文显示为 或乱码。

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

  • 最兼容方案:启用 ZIP 的 UTF-8 标志位 —— 设置 header.Flags = 1 (即 zip.UseUTF8),且确保 Name 是合法 UTF-8 字符串
  • 注意:老版本 Windows(如 Win7)原生解压程序不支持该标志,会忽略文件名直接解压;此时只能改用拼音/英文名,或依赖 7-Zip / The Unarchiver 等现代工具
  • 不要尝试用 gobindata 或 base64 编码文件名,这会让 ZIP 失去通用性
func createZipWithUTF8(filename string, files map[string][]byte) error {
    f, _ := os.Create(filename)
    defer f.Close()
    w := zip.NewWriter(f)
    defer w.Close()

    for name, content := range files {
        header := &zip.FileHeader{
            Name:   name,
            Method: zip.Deflate,
            Flags:  1 << 11, // 启用 UTF-8
        }
        header.SetModTime(time.Now())
        fw, _ := w.CreateHeader(header)
        fw.Write(content)
    }
    return w.Close()
}
路径处理、编码标志、流关闭顺序这三处,稍有疏忽就会产出看似正常实则无法通用的归档文件。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

177

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

226

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

336

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

208

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

388

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

194

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

189

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

191

2025.06.17

Golang 分布式缓存与高可用架构
Golang 分布式缓存与高可用架构

本专题系统讲解 Golang 在分布式缓存与高可用系统中的应用,涵盖缓存设计原理、Redis/Etcd集成、数据一致性与过期策略、分布式锁、缓存穿透/雪崩/击穿解决方案,以及高可用架构设计。通过实战案例,帮助开发者掌握 如何使用 Go 构建稳定、高性能的分布式缓存系统,提升大型系统的响应速度与可靠性。

58

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.5万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.5万人学习

Git中文开发手册
Git中文开发手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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