如何在Golang中解压文件_Golang compress/gzip解压操作方法
技术百科
P粉602998670
发布时间:2026-01-01
浏览: 次 gzip.Reader读取压缩流时必须显式检查io.EOF,因它不会自动返回;推荐用io.Copy解压,若需逐块读则每次检查n和err;解压tar.gz需正确嵌套gzip.NewReader与tar.NewReader,并严格按Header.Size读取。
gzip.Reader 读取压缩流时必须检查 io.EOF
Go 的 gzip.Reader 不会在读完所有数据后自动返回 io.EOF,而是可能在解压末尾仍返回 nil 错误、但后续再读一次才触发 io.EOF。不显式处理会导致循环卡死或漏数据。
- 用
io.Copy直接解压到目标io.Writer是最安全的方式,它内部已正确处理io.EOF - 若需逐块读取(如校验、限速),每次
Read后必须检查返回的n和err:当err == io.EOF或n == 0 && err == nil时停止 - 别依赖
gzip.Reader.Close()来判断流是否结束——它只释放资源,不反映数据边界
解压单个 .gz 文件到磁盘的最小可靠写法
注意文件路径、权限和错误传播。Go 标准库不会自动创建父目录,也不会覆盖只读文件。
- 先用
os.Open打开.gz文件,失败直接返回 - 用
gzip.NewReader包装,记得在函数退出前调用gr.Close() - 目标文件名建议去掉
.gz后缀(可用strings.TrimSuffix(name, ".gz")),并用os.Create创建;若需保留原始权限,得从源文件Stat()中提取Mode() - 用
io.Copy转发数据,它会自动处理缓冲与错误中断
func gunzipFile(src, dst string) error {
f, err := os.Open(src)
if err != nil {
return err
}
defer f.Close()
gr, err := gzip.NewReader(f)
if err != nil {
return err
}
de
fer gr.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, gr)
return err
}
解压 tar.gz 时别直接用 gzip.NewReader 套 tar.NewReader
tar.gz 是两层封装:外层 gzip、内层 tar。常见错误是先解压整个流到内存再解析 tar,或漏掉 tar.Header.Size 导致读取错位。
- 必须用
gzip.NewReader包装原始*os.File,再把该gzip.Reader传给tar.NewReader -
tar.Reader.Next()每次返回一个文件头,之后必须用io.CopyN或循环读取恰好hdr.Size字节,不能读到io.EOF—— 否则会污染下一个文件头的读取位置 - 目标路径需用
filepath.Clean(hdr.Name)防止../路径遍历,且要提前os.MkdirAll(filepath.Dir(dst), 0755)
gzip.Reader 初始化失败的典型错误信息
遇到这些提示,基本可定位为输入源问题:
-
gzip: invalid header:文件不是 gzip 格式,或开头被截断(比如 HTTP 响应体含 chunked 编码未解码) -
gzip: invalid checksum:数据损坏,或写入时未调用gzip.Writer.Close()导致尾部 CRC 缺失 -
unexpected EOF:文件不完整,常见于网络下载中断后直接解压 - 空文件或 0 字节文件会触发
gzip: invalid header,需在gzip.NewReader前加fi, _ := f.Stat(); if fi.Size() == 0 { return errors.New("empty gzip file") }
Close()、别跳过 Stat() 检查、别信输入源一定合规。
# 的是
# 能在
# 它会
# 错误信息
# 若需
# 则会
# 再把
# 先用
# http
# go
# golang
# 循环
# if
# 编码
# 字节
# 标准库
# nil
# 封装
# 解压
# 继承
# 遍历
# copy
# 读到
# EOF
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win11怎么关闭搜索历史_Win11清除设备上的
- Win10系统怎么查看显卡温度_Win10任务管理
- Win11怎么关闭自动调节屏幕亮度_Windows
- Linux怎么设置磁盘配额_Linux系统Quot
- Win11怎么修改DNS服务器 Win11设置DN
- Win11怎么关闭通知消息_屏蔽Windows 1
- 如何将竖排文本文件转换为横排字符串
- Win11怎么快速锁屏_Win11一键锁屏快捷键W
- Win11怎么查看电脑配置_Win11硬件配置详细
- 如何高效识别并拦截拼接式恶意域名 spam
- PHP 中 require() 语句返回值的用法详
- 如何解决Windows时间不准的问题?(自动同步设
- 如何在Golang中引入测试模块_Golang测试
- c++中explicit(bool)的用法 c++
- Mac如何与安卓手机传文件_Mac和Android
- Win10电脑怎么设置IP地址_Windows10
- Windows10电脑怎么设置自动连接WiFi_W
- Python字符串处理进阶_切片方法解析【指导】
- Win10怎么设置开机密码_Windows10账户
- Windows 11登录时提示“用户配置文件服务登
- Golang如何避免指针逃逸_Golang逃逸分析
- 如何使用正则表达式提取以编号开头、后跟多个注解的完
- Win11怎么设置DNS服务器_Windows11
- VSC怎样在VSC中调试PHPAPI_接口调试技巧
- 如何在 Go 中正确初始化结构体中的 map 字段
- 如何优化Golang Web性能_Golang H
- 如何使用Golang实现容器安全扫描_Golang
- Mac如何查看电池健康百分比_Mac系统信息电源检
- 新手学PHP架构总混淆概念咋办_重点梳理【教程】
- php和redis连接超时怎么办_phpredis
- ACF 教程:如何正确更新嵌套在多层 Group
- Win10如何更改用户账户控制_Windows10
- php修改数据怎么批量改状态_批量更新status
- 如何使用正则表达式提取以编号开头、后接多个注解的逻
- Win11时间不对怎么同步_Win11自动校准互联
- 如何使用Golang管理模块版本_Golanggo
- 如何使用Golang匿名函数_快速定义临时函数逻辑
- c++如何用AFL++进行模糊测试 c++ Fuz
- Win11如何设置系统语言_Win11系统语言切换
- php打包exe怎么传递参数_命令行参数接收方法【
- 如何在 Python 中将 ISO 8601 时间
- Win10电脑C盘红了怎么清理_Windows10
- Win11怎么关闭OneDrive同步_Win11
- Win10系统映像怎么恢复 Win10使用系统映像
- mac怎么安装adb_MAC配置Android A
- Win11怎么关闭资讯和兴趣_Windows11任
- Python并发安全问题_资源竞争说明【指导】
- Win11屏幕亮度突然变暗怎么解决_自动变暗问题处
- c# 在高并发场景下,委托和接口调用的性能对比
- 如何使用Golang实现微服务状态监控_Golan

fer gr.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, gr)
return err
}
QQ客服