尝试从文件和目录创建tar.gz文件时出现“写得太长”错误

蓝色机器人:

所以我试图从多个目录和文件创建一个tar.gz文件。具有与以下用法相同的用法:

tar -cvzf sometarfile.tar.gz somedir/ someotherdir/ somefile.json somefile.xml

假设目录中还有其他目录。我将其作为输入:

    paths := []string{
      "somedir/",
      "someotherdir/",
      "somefile.json",
      "somefile.xml",
    }

并使用这些:

    func TarFilesDirs(paths []string, tarFilePath string ) error {
       // set up the output file
       file, err := os.Create(tarFilePath)
       if err != nil {
           return err
       }

       defer file.Close()
       // set up the gzip writer
       gz := gzip.NewWriter(file)
       defer gz.Close()

       tw := tar.NewWriter(gz)
       defer tw.Close()

       // add each file/dir as needed into the current tar archive
       for _,i := range paths {
          if err := tarit(i, tw); err != nil {
               return err
          }
       }

       return nil
   }

func tarit(source string, tw *tar.Writer) error {
    info, err := os.Stat(source)
    if err != nil {
        return nil
    }

    var baseDir string
    if info.IsDir() {
        baseDir = filepath.Base(source)
    }

    return filepath.Walk(source,
        func(path string, info os.FileInfo, err error) error {
            if err != nil {
                return err
            }

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

            if baseDir != "" {
                header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source))
            }

            if err := tw.WriteHeader(header); err != nil {
                return err
            }

            if info.IsDir() {
                return nil
            }

            file, err := os.Open(path)
            if err != nil {
                return err
            }

            defer file.Close()

            _, err = io.Copy(tw, file)
            if err != nil {
                log.Println("failing here")
                return err
            }

            return err
        })
}

问题:如果目录很大,我将得到:

archive/tar: write too long

错误,当我将其删除时,一切正常。

花了很多时间在寻找解决方案上的想法...

有任何想法吗?

谢谢

user7009112:

在我更仔细地查看tar.FileInfoHeader doc之前,我遇到了类似的问题:

FileInfoHeader从fi创建一个部分填充的Header。如果fi描述了符号链接,则FileInfoHeader会将链接记录为链接目标。如果fi描述目录,则名称后会加上斜杠。由于os.FileInfo的Name方法仅返回其描述的文件的基本名称,因此可能有必要修改返回的标头的Name字段以提供文件的完整路径名。

本质上,在使用WriteHeader编写文件之前,不保证FileInfoHeader会填写所有标头字段,并且如果您查看实现,则Size字段仅在常规文件上设置您的代码段似乎仅处理目录,这意味着如果遇到任何其他非常规文件,则将头的大小写为零,然后尝试将磁盘上大小可能为非零的特殊文件复制到tar中。Go返回ErrWriteTooLong以阻止您创建损坏的tar。

我想到了这一点,此后就再也没有问题了。

    if err := filepath.Walk(directory, func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return check(err)
        }

        var link string
        if info.Mode()&os.ModeSymlink == os.ModeSymlink {
            if link, err = os.Readlink(path); err != nil {
                return check(err)
            }
        }

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

        header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, directory))
        if err = tw.WriteHeader(header); err != nil {
            return check(err)
        }

        if !info.Mode().IsRegular() { //nothing more to do for non-regular
            return nil
        }

        fh, err := os.Open(path)
        if err != nil {
            return check(err)
        }
        defer fh.Close()

        if _, err = io.CopyBuffer(tw, fh, buf); err != nil {
            return check(err)
        }
        return nil
})

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

创建.tar.gz文件时不包括目录

创建tar归档文件时添加目录

当我尝试将文件夹添加到存档时,出现错误:路径太长

发送.tar.gz文件时出现卷曲错误56“从对等方接收数据时失败”

尝试创建TAR存档,但排除.messages文件

Perl tar文件以递归方式创建目录

文件名使用subprocess.call读取pcap文件时出现太长的错误

根据tar文件创建目录名称后提取tar

提取.tar.gz文件时出现问题

从包含500000个文件的目录中创建许多tar文件

如何创建包含目录中所有文件的tar文件

文件存在,但出现mv错误并显示:“ mv:无法统计'file.tar.gz':没有此类文件或目录”

将tar.gz文件解压缩到目录并创建目录(如果不存在)

创建目录时出现只读文件系统错误?

在子目录中创建一个包含以 C 开头的文件的 tar.gz 文件

当文件存储在不同目录中时,创建不包含父目录的tar归档文件

错误:ENOENT:没有这样的文件或目录,尝试创建目录时使用 mkdir

尝试创建jar时清单文件中的行太长

是否可以将zip和tar.gz文件作为目录集成到文件系统中

当“文件名太长”时,删除robocopy创建的递归目录

创建当前目录的tar归档文件,不带前期

在shell脚本中的指定目录中创建tar文件

创建不包含父目录的tar归档文件

创建目录的tar存档,隐藏文件除外?

Tar创建并将文件拆分为子目录

创建具有多个目录和文件位置的tar

tar创建档案文件重命名根目录

是否可以在目录A中运行tar命令,从而从目录C中的文件中在目录B中创建tar归档文件?

FFMPEG出现错误-文件名或扩展名太长