首页 > 后端开发 > Golang > 正文

使用 Go 语言创建包含目录结构的 Tar Gzip 文件

聖光之護
发布: 2025-09-23 16:27:35
原创
775人浏览过

使用 go 语言创建包含目录结构的 tar gzip 文件

本文档详细介绍了如何使用 Go 语言创建一个包含完整目录结构的 tar.gz 压缩文件。通过递归遍历目录,并将每个文件和目录的完整路径信息添加到 tar 归档中,最终生成一个可以在 Linux 等系统上正确解压并还原目录结构的压缩包。本文提供代码示例,并解释了关键步骤,帮助开发者理解并实现该功能。

创建 Tar Gzip 文件的 Go 语言教程

本教程将指导你如何使用 Go 语言创建一个 tar.gz 文件,该文件能够完整地保留目录结构。核心思路是递归遍历目标目录,并将每个文件或目录的完整路径添加到 tar 归档中。

核心代码实现

以下代码展示了如何实现将目录及其内容压缩到 tar.gz 文件的功能。

package main

import (
    "archive/tar"
    "compress/gzip"
    "fmt"
    "io"
    "log"
    "os"
    "path/filepath"
    "strings"
)

func handleError(_e error) {
    if _e != nil {
        log.Fatal(_e)
    }
}

func TarGzWrite(_path string, tw *tar.Writer, fi os.FileInfo) {
    fr, err := os.Open(_path)
    handleError(err)
    defer fr.Close()

    h := new(tar.Header)
    h.Name = _path // 使用完整路径
    h.Size = fi.Size()
    h.Mode = int64(fi.Mode())
    h.ModTime = fi.ModTime()

    err = tw.WriteHeader(h)
    handleError(err)

    _, err = io.Copy(tw, fr)
    handleError(err)
}

func IterDirectory(dirPath string, tw *tar.Writer) {
    dir, err := os.Open(dirPath)
    handleError(err)
    defer dir.Close()
    fis, err := dir.Readdir(0)
    handleError(err)
    for _, fi := range fis {
        curPath := filepath.Join(dirPath, fi.Name()) // 使用 filepath.Join 构建路径
        if fi.IsDir() {
            // 添加目录本身
            hdr := &tar.Header{
                Name:    curPath,
                Mode:    0755, // 目录权限
                ModTime: fi.ModTime(),
                Typeflag: tar.TypeDir,
            }
            if err := tw.WriteHeader(hdr); err != nil {
                log.Fatal(err)
            }
            IterDirectory(curPath, tw) // 递归调用
        } else {
            fmt.Printf("adding... %s\n", curPath)
            TarGzWrite(curPath, tw, fi)
        }
    }
}

func TarGz(outFilePath string, inPath string) {
    // file write
    fw, err := os.Create(outFilePath)
    handleError(err)
    defer fw.Close()

    // gzip write
    gw := gzip.NewWriter(fw)
    defer gw.Close()

    // tar write
    tw := tar.NewWriter(gw)
    defer tw.Close()

    // 添加根目录
    fi, err := os.Stat(inPath)
    handleError(err)

    hdr, err := tar.FileInfoHeader(fi, fi.Name())
    handleError(err)
    hdr.Name = inPath

    if err := tw.WriteHeader(hdr); err != nil {
        log.Fatal(err)
    }

    IterDirectory(inPath, tw)

    fmt.Println("tar.gz ok")
}

func main() {
    targetFilePath := "test.tar.gz"
    inputDirPath := "test/"
    TarGz(targetFilePath, strings.TrimRight(inputDirPath, "/"))
    fmt.Println("Hello, World")
}
登录后复制

代码解释

  1. TarGzWrite 函数: 此函数负责将单个文件写入 tar 归档。关键在于 h.Name = _path 这一行,它使用文件的完整路径作为 tar 归档中的文件名,从而保留目录结构。
  2. IterDirectory 函数: 此函数递归地遍历目录。对于每个目录,它递归调用自身。对于每个文件,它调用 TarGzWrite 函数将其写入 tar 归档。特别要注意的是,需要为目录本身添加 tar.Header,并将 Typeflag 设置为 tar.TypeDir。
  3. TarGz 函数: 此函数是入口函数,它创建输出文件、gzip 写入器和 tar 写入器,然后调用 IterDirectory 函数开始遍历和写入。添加根目录是必要的,否则解压时会缺少根目录。

使用示例

假设你的目录结构如下:

TTS Free Online免费文本转语音
TTS Free Online免费文本转语音

免费的文字生成语音网站,包含各种方言(东北话、陕西话、粤语、闽南语)

TTS Free Online免费文本转语音 37
查看详情 TTS Free Online免费文本转语音
test/
├── 0.txt
└── 1
    └── 1.txt
登录后复制

运行上述代码后,会生成 test.tar.gz 文件。使用 tar -tvf test.tar.gz 命令查看内容,你应该看到类似如下的输出:

drwxr-xr-x  0 0      0       0 2023-10-27 14:55 test/
-rw-r--r--  0 0      0       0 2023-10-27 14:55 test/0.txt
drwxr-xr-x  0 0      0       0 2023-10-27 14:55 test/1/
-rw-r--r--  0 0      0       0 2023-10-27 14:55 test/1/1.txt
登录后复制

这表明 tar.gz 文件中正确地保留了目录结构。

注意事项

  • 路径处理: 使用 filepath.Join 来构建路径,以确保跨平台兼容性。
  • 目录权限: 在创建目录的 tar.Header 时,需要设置适当的权限 (Mode) 和 Typeflag。
  • 错误处理: 务必进行充分的错误处理,以确保程序的健壮性。
  • 添加根目录: 务必在递归遍历前,添加根目录,否则解压时会缺少根目录。

总结

通过以上步骤,你可以使用 Go 语言创建一个包含完整目录结构的 tar.gz 文件。关键在于正确地处理路径,并在 tar 归档中包含每个文件和目录的完整路径信息。 希望本教程能够帮助你理解并实现该功能。

以上就是使用 Go 语言创建包含目录结构的 Tar Gzip 文件的详细内容,更多请关注php中文网其它相关文章!

相关标签:
最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门推荐
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

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