如何在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; ?>
】
相关推荐
- Windows10系统怎么查看显卡型号_Win10
- Windows10如何更改计算机工作组_Win10
- Win11怎么连接投影仪_Win11多显示器投屏设
- Win11怎么关闭资讯和兴趣_Windows11任
- Windows10系统怎么查看设备管理器_Win1
- 如何使用Golang实现微服务状态监控_Golan
- Win11怎么恢复旧版开始菜单_通过软件还原Win
- Windows10电脑怎么设置电源按钮_Win10
- Win11如何设置开机自动联网 Win11宽带连接
- Windows系统时间服务错误_W32Time服务
- Win11搜索栏无法输入_解决Win11开始菜单搜
- 如何在 Django 中安全修改用户密码而不使会话
- VSC怎么创建PHP项目_从零开始搭建项目的步骤【
- PHP接收参数值为空怎么办_判断和处理空参数方法说
- Win11怎么设置多显示器任务栏 Win11扩展任
- c++中如何使用虚函数实现多态_c++多态性实现原
- Mac如何彻底清理浏览器缓存?(Safari与Ch
- MAC如何启用访达侧边栏显示_MAC Finder
- Win10如何更改网络连接_Windows10以太
- Win11怎样安装网易云音乐_Win11安装网易云
- Win11声音忽大忽小怎么办 Win11音频增强功
- php订单日志怎么按金额排序_php按订单金额排序
- Win11快速助手怎么用_Win11远程协助连接教
- Win11如何设置电源计划_Win11电源计划优化
- Win10电脑怎么设置网络名称_Windows10
- Win11开机自检怎么关闭_跳过Win11开机磁盘
- LINUX如何查看文件类型_Linux中file命
- 为什么本地php环境运行php脚本卡顿_php执行
- 如何在 Pandas 中按元素交集合并两列字符串
- Python对象生命周期管理_创建销毁解析【教程】
- 如何开启Windows的远程服务器管理工具(RSA
- Windows服务持续崩溃怎样修复_系统服务保护机
- Win11讲述人怎么关闭_Win11误触开启语音朗
- Win11时间不对怎么同步_Win11自动校准互联
- Win11怎样彻底卸载自带应用_Win11彻底卸载
- c++中如何使用std::variant_c++1
- Win11怎么清理C盘OneDrive缓存_Win
- 如何在Golang中理解指针比较_Golang地址
- Python函数接口文档化_自动化说明【指导】
- 如何使用Golang实现容器健康检查_监控和自动重
- Python函数缓存机制_lru_cache解析【
- php打包exe怎么传递参数_命令行参数接收方法【
- 如何在Golang中使用replace替换模块_指
- Win11怎么关闭内容自适应亮度_Windows1
- php转exe用什么工具打包快_高效打包软件推荐【
- Win11怎样安装剪映专业版_Win11安装剪映教
- php中作用域操作符能访问私有静态属性吗_访问权限
- Python与GPU加速技术_CUDA与Numba
- Win11如何添加/删除输入法 Win11切换中英
- Linux怎么查找死循环进程_Linux系统负载分

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