Go语言如何实现文件压缩解压_Golang工具项目

老明同学_6484

老明同学_6484

2026-01-18

614人浏览

原创

Go用archive/zip压缩文件打不开,主因是header.Name未转义路径分隔符(需将替换为/)、未调用zipWriter.Close()致EOCD缺失;解压时须用filepath.Clean校验路径防穿越;大文件需流式处理避免内存溢出。

go语言如何实现文件压缩解压_golang工具项目

Go 语言用 archive/zip 压缩文件时,为什么生成的 zip 打不开?

常见原因是没正确设置 zip.FileHeader.Name,或忽略了路径分隔符转换。Windows 下路径是 ,而 ZIP 规范强制要求使用 /。直接写入本地路径会导致解压失败或目录结构错乱。

  • 必须将文件路径中的 替换为 /,再赋给 header.Name
  • 若压缩的是目录,需手动遍历(filepath.WalkDir),对每个文件调用 zipWriter.CreateHeader
  • 别忘了调用 zipWriter.Close() —— 否则 zip 文件末尾缺少 EOCD(End of Central Directory)记录,绝大多数解压工具会报“损坏”
fh, _ := zip.FileInfoHeader(fi)
fh.Name = strings.ReplaceAll(filePath, "\", "/") // 关键
fh.Name = strings.TrimPrefix(fh.Name, basePath+"/")
w, _ := zw.CreateHeader(fh)
io.Copy(w, f)

解压 zip 到指定目录时,如何防止路径穿越(path traversal)攻击?

用户提供的 zip 包可能包含恶意路径如 ../../../etc/passwd,直接用 header.Name 创建文件会覆盖系统关键位置。必须做白名单校验。

  • 用 filepath.Clean(header.Name) 归一化路径
  • 检查归一化后路径是否仍以目标解压根目录为前缀(用 strings.HasPrefix + filepath.ToSlash 统一分隔符)
  • 拒绝任何含 ".." 或以 "/" 开头的 Name
cleanName := filepath.Clean(header.Name)
if strings.Contains(cleanName, "..") || strings.HasPrefix(cleanName, "/") {
    return fmt.Errorf("illegal path: %s", header.Name)
}
dstPath := filepath.Join(destDir, cleanName)
if !strings.HasPrefix(filepath.ToSlash(dstPath), filepath.ToSlash(destDir)+"/") {
    return fmt.Errorf("escaping from target dir: %s", header.Name)
}

需要同时支持 tar.gz 和 zip,该选 archive/tar 还是第三方库?

Go 标准库已完整支持 archive/tar + compress/gzip 组合,无需引入外部依赖。但要注意:tar 本身不压缩,gzip 是外层封装,解压时要先 gzip.NewReader,再传给 tar.NewReader。

windows-auto
windows-auto

Windows 桌面自动化技能,支持鼠标控制(移动/点击/拖拽/滚轮/截图)、键盘输入(文字输入/按键/组合键)、窗口管理(查找/聚焦/最大化/最小化/关闭/移动)、截图并发送文件。提供两种截图方式:Python pyautogui 截图(集成在自动化流程中)和 PowerShell + .NET 零依赖截图(支持区域截图和多显示器)。当用户需要自动化 Windows 桌面操作、控制鼠标键盘、管理窗口、执行 GUI 自动化任务、截图发送文件时使用。

下载
  • archive/zip 是单库全功能;archive/tar 必须搭配 compress/* 子包使用
  • tar.gz 解压比 zip 略快(无中央目录解析开销),但 zip 支持随机访问单个文件,tar 需顺序扫描
  • 若项目需跨平台兼容性(尤其 Windows 用户双击解压),zip 更稳妥;若面向 Linux 服务器批量归档,tar.gz 更轻量

大文件压缩卡住或内存爆掉,怎么流式处理?

别把整个文件读进 []byte 再写入 zip —— 这会让内存占用飙升到文件大小的 2–3 倍。所有操作必须基于 io.Reader / io.Writer 流式完成。

  • 压缩时:用 os.Open 获取 *os.File,直接 io.Copy(zipWriter, file)
  • 解压时:从 zip.File.Open() 拿到 io.ReadCloser,同样流式写入目标文件
  • 对超大文件(>1GB),可加 bufio.Writer 提升写入效率,但注意别在 zip 内部嵌套缓冲(标准库已优化)

真正容易被忽略的是错误传播:流式操作中任一环节出错(如磁盘满、权限不足),必须立刻中断并清理已创建的临时文件,否则留下残缺 zip 或空目录。

golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Go中Type关键字的用法
Go中Type关键字的用法

Go中Type关键字的用法有定义新的类型别名或者创建新的结构体类型。本专题为大家提供Go相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.06

3109

5

go怎么实现链表
go怎么实现链表

go通过定义一个节点结构体、定义一个链表结构体、定义一些方法来操作链表、实现一个方法来删除链表中的一个节点和实现一个方法来打印链表中的所有节点的方法实现链表。

2023.09.25

6207

6

go语言编程软件有哪些
go语言编程软件有哪些

go语言编程软件有Go编译器、Go开发环境、Go包管理器、Go测试框架、Go文档生成器、Go代码质量工具和Go性能分析工具等。本专题为大家提供go语言相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.13

742

5

0基础如何学go语言
0基础如何学go语言

0基础学习Go语言需要分阶段进行,从基础知识到实践项目,逐步深入。php中文网给大家带来了go语言相关的教程以及文章,欢迎大家前来学习。

2023.10.26

7965

20

Go语言实现运算符重载有哪些方法
Go语言实现运算符重载有哪些方法

Go语言不支持运算符重载,但可以通过一些方法来模拟运算符重载的效果。使用函数重载来模拟运算符重载,可以为不同的类型定义不同的函数,以实现类似运算符重载的效果,通过函数重载,可以为不同的类型实现不同的操作。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

2916

5

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

3164

5

go语言开发工具大全
go语言开发工具大全

本专题整合了go语言开发工具大全,想了解更多相关详细内容,请阅读下面的文章。

2025.06.11

6959

12

go语言引用传递
go语言引用传递

本专题整合了go语言引用传递机制,想了解更多相关内容,请阅读专题下面的文章。

2025.06.26

4437

12

go语言版本升级
go语言版本升级

本专题整合了go语言版本升级方法,想了解更多相关内容,请阅读专题下面的文章。

2025.06.27

8010

16

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习