0

0

Golang 中使用 tar 包打包文件时正确保留原始权限的完整指南

聖光之護

聖光之護

发布时间:2026-01-20 09:39:59

|

136人浏览过

|

来源于php中文网

原创

Golang 中使用 tar 包打包文件时正确保留原始权限的完整指南

golang 中使用 tar 包打包文件时正确保留原始权限的完整指南:go 的 `archive/tar` 包默认不自动继承文件权限,需显式通过 `tar.fileinfoheader` 构建包含 mode、mtime 等元信息的 header,否则解压后文件权限将丢失(如变为 000),导致无法读取。

在 Go 中手动构造 tar 归档时,一个常见误区是仅设置 Header.Name 和 Header.Size 字段(如问题代码所示),而忽略文件权限(Mode)、修改时间(ModTime)、用户/组 ID(Uid/Gid)等关键元数据。这会导致生成的 tar 文件中对应条目权限位为 000,解压后目标文件不可读、不可执行,必须额外执行 chmod 才能使用。

✅ 正确做法:使用 tar.FileInfoHeader

tar.FileInfoHeader(fi, link) 是标准库提供的工具函数,它会基于 os.FileInfo 自动填充完整的 header 字段,包括:

  • Mode(含权限位与文件类型,如 0644 或 0755)
  • ModTime
  • Uid / Gid
  • Size
  • Typeflag(自动识别普通文件、目录、符号链接等)
hdr, err := tar.FileInfoHeader(fi, "")
if err != nil {
    log.Fatalln("failed to create header:", err)
}

⚠️ 注意:fi.Name() 仅返回文件名(不含路径),因此若需归档带路径的文件(如 "data/config.json"),必须手动修正 hdr.Name

hdr.Name = "data/config.json" // 覆盖默认的 base name

✨ 进阶优化:避免内存加载,用 io.Copy

原代码调用 ioutil.ReadFile() 将整个文件读入内存,对大文件极不友好。应直接流式写入:

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

沁言学术
沁言学术

你的论文写作AI助理,永久免费文献管理工具,认准沁言学术

下载
// ✅ 推荐:零拷贝、低内存占用
_, err := io.Copy(tw, f)
if err != nil {
    log.Fatalln("failed to write file content:", err)
}

完整修复版示例(含错误处理与日志):

package main

import (
    "archive/tar"
    "io"
    "log"
    "os"
)

func main() {
    // 创建 tar 输出文件
    outFile, err := os.Create("/path/to/tar/file/test.tar")
    if err != nil {
        log.Fatalln("failed to create tar file:", err)
    }
    defer outFile.Close()

    tw := tar.NewWriter(outFile)
    defer tw.Close() // 确保 Close() 被调用,完成归档尾部写入

    // 打开源文件
    f, err := os.Open("sample.txt")
    if err != nil {
        log.Fatalln("failed to open source file:", err)
    }
    defer f.Close()

    fi, err := f.Stat()
    if err != nil {
        log.Fatalln("failed to stat file:", err)
    }

    // ✅ 关键:用 FileInfoHeader 自动填充权限等元数据
    hdr, err := tar.FileInfoHeader(fi, "")
    if err != nil {
        log.Fatalln("failed to create header:", err)
    }
    hdr.Name = "sample.txt" // 显式设置归档内路径(可扩展为子目录)

    if err := tw.WriteHeader(hdr); err != nil {
        log.Fatalln("failed to write header:", err)
    }

    // ✅ 流式写入,高效且内存安全
    written, err := io.Copy(tw, f)
    if err != nil {
        log.Fatalln("failed to copy file content:", err)
    }
    log.Printf("Successfully archived %s (%d bytes)", hdr.Name, written)
}

? 验证权限是否生效

打包后可通过命令行验证:

# 查看 tar 中文件权限
tar -tvf /path/to/tar/file/test.tar

# 解压并检查
tar -xvf test.tar
ls -l sample.txt  # 应显示如 -rw-r--r--(即 0644)

? 总结要点

  • ❌ 错误:手动构造 tar.Header 且只设 Name/Size → 权限丢失;
  • ✅ 正确:始终优先使用 tar.FileInfoHeader(fi, link);
  • ? 路径处理:FileInfoHeader 不含路径,需手动赋值 hdr.Name 以支持目录结构;
  • ⚡ 性能:用 io.Copy 替代 ioutil.ReadFile + tw.Write,避免 OOM;
  • ? 清理:务必 defer tw.Close() —— 它会写入 tar 结束标记,缺失将导致解压失败。

遵循以上实践,即可生成符合 POSIX 权限语义、跨平台兼容的标准 tar 归档。

相关专题

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

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

179

2024.02.23

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

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

228

2024.02.23

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

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

340

2024.02.23

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

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

209

2024.03.05

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

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

392

2024.05.21

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

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

197

2025.06.09

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

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

191

2025.06.10

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

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

192

2025.06.17

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

0

2026.01.20

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.4万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.2万人学习

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

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