gpt4 book ai didi

linux - Golang 压缩目录

转载 作者:IT王子 更新时间:2023-10-29 02:13:21 26 4
gpt4 key购买 nike

我无法弄清楚如何将目录写入 tarball 的 headerinfo。例如,我有这个目录结构:

test [dir]
-- test1.txt
-- subDirA [sub dir]
-- test2.txt

如果我使用我的 Go tar 可执行文件对测试进行压缩,它将解压缩并具有原始结构。如果我在 tarball 上执行 tar -tvf,列表将是:

test/test1.txt 
test/subDirA/test2.txt

但是,如果我手动执行 tar -cvf 测试,然后执行 tar -tvf,列表将是:

test/
test/test1.txt
test/subDirA/
test/subDirA/test2.txt

这也是我希望我的 Go tarring 程序做的。在我的 Go 程序中,我尝试添加一个新方法 writeDirToTar 来处理将目录添加到 tarWriter 中。我从 fileWalk 函数调用 writeFileToTar 或 writeDirToTar。当我在 writeDirToTar 中调用 io.Copy(tarWriter, file) 时,出现“test/subDirA is a directory”错误,这是有道理的。有解决办法吗?

func writeToTar(fileDir string,
sourceBase string,
tarWriter *tar.Writer,
f os.FileInfo) error {

file, err := os.Open(fileDir)
if err != nil {
log.Print("error opening file")
return err
}
defer file.Close()

// relative paths are used to preserve the directory paths in each file path
relativePath, err := filepath.Rel(sourceBase, fileDir)

tarheader := new(tar.Header)
tarheader.Name = relativePath
tarheader.Size = f.Size()
tarheader.Mode = int64(f.Mode())
tarheader.ModTime = f.ModTime()

err = tarWriter.WriteHeader(tarheader)
if err != nil {
log.Print("error writing tarHeader")
return err
}
_, err = io.Copy(tarWriter, file)
if err != nil {
log.Print("error writing to tarWriter")
return err
}
return nil
}

func writeDirToTar(fileDir string,
sourceBase string,
tarWriter *tar.Writer,
f os.FileInfo) error {

file, err := os.Open(fileDir)
if err != nil {
log.Print("error opening file")
return err
}
defer file.Close()

// relative paths are used to preserve the directory paths in each file path
relativePath, err := filepath.Rel(sourceBase, fileDir)

if tarHeader, err := tar.FileInfoHeader(f, relativePath); err != nil {
log.Print("error writing tarHeader")
return err
}

tarHeader.Name = relativePath
tarheader.Mode = int64(f.Mode())
tarheader.ModTime = f.ModTime()

_, err = io.Copy(tarWriter, file)
if err != nil {
log.Print("error writing to tarWriter")
return err
}
return nil

}

最佳答案

您缺少 tar.Header 中的 Typeflag 字段。

对于您至少需要的目录:

tarheader := &tar.Header{
Name: relativePath,
Mode: int64(f.Mode()),
ModTime: f.ModTime(),
Typeflag: tar.TypeDir,
}

这里不需要大小,也不需要复制目录数据,因为内部目录数据结构对 tar 没有任何意义。

您可能还想在文件名中添加 / 以直观地指示它是一个目录并匹配 POSIX tar 行为。

或者你可以只使用 tar.FileInfoHeader功能就像您对文件所做的那样,以创建正确的标题结构。

关于linux - Golang 压缩目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39646584/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com