gpt4 book ai didi

unix - 有没有办法用 Go 复制 tar -h 选项?

转载 作者:IT王子 更新时间:2023-10-29 02:22:08 25 4
gpt4 key购买 nike

在 Unix 中,tar 实用程序有一个 -h 选项,用于归档链接的目标。我想知道是否有办法用 Go 做到这一点。现在,当我尝试将标题名称设置为符号链接(symbolic link)文件的链接内容复制到 tar 时,出现了 tar: Damaged tar archive 错误。下面的代码是我目前正在使用的。该函数的目标是递归地对当前目录中的所有内容进行压缩。

我想也许我所要做的就是将符号链接(symbolic link)的大小设置为目标文件的大小,但仍然出现错误。

func createTarFile() {
tarfile, _ := os.Create(buildCtxTar)
defer tarfile.Close()

tarball := tar.NewWriter(tarfile)
defer tarball.Close()

//get the working directory
rootDir, _ := os.Getwd()

//add all the files in the current directory to the tarball
walkFn := func(path string, info os.FileInfo, err error) error {
//don't add the tar file to itself, don't add the working directory either
if info.Name() == buildCtxTar || info.Name() == filepath.Base(rootDir) {
return nil
}

//no absolute paths in the tar file, the "+1" strips the leading file separator
relativePath := path[len(rootDir)+1:]

isSymlink := info.Mode()&os.ModeSymlink == os.ModeSymlink
var size int64 = -1
//evaluate symbolic links
if isSymlink {
path, size, err = handleSymlink(path)
if err != nil {
return err
}
}

header, err := tar.FileInfoHeader(info, path)
if err != nil {
return err
}

//if the OS is windows we need to convert the '\' to '/'
relativePath = filepath.ToSlash(relativePath)

//rename the name of the file to its path for a structured tarball
header.Name = relativePath
if isSymlink {
header.Size = size
}
if err := tarball.WriteHeader(header); err != nil {
return err
}

//don't attempt copy data from special files (like directories)
if !isSymlink && !info.Mode().IsRegular() {
return nil
}
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()

// copy the file data to the tarball
if _, err := io.Copy(tarball, f); err != nil {
return err
}
return nil
}

//walks through all files and subdirectories of the current directory
err := filepath.Walk(rootDir, walkFn)
}

//get the filepath for the symbolic link
func handleSymlink(path string) (string, int64, error) {
//read the link
link, err := os.Readlink(path)
if err != nil {
return "", -1, err
}
//if the filepath isn't an absolute path we need to
//reconstruct it so that it is
if !filepath.IsAbs(link) {
link = filepath.Join(filepath.Dir(path), link)
if err != nil {
return "", -1, err
}
}
fi, err := os.Stat(link)
if err != nil {
return "", -1, err
}
size := fi.Size()
return link, size, nil
}

最佳答案

您正在从符号链接(symbolic link) FileInfo 创建 tar.Header,它仍将具有 TypeflagMode 符号链接(symbolic link)。

从目标文件创建一个新的 header ,并通过将名称字段更改为符号链接(symbolic link)的名称来将其“移动”到存档中。

关于unix - 有没有办法用 Go 复制 tar -h 选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42984121/

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