在使用Golang打包目录时,tar命令中的typeflag参数应该填写哪个值,是directory还是file?

3
我不确定如何在tar一个带有文件和子目录的目录时设置Header.Typeflag。我知道如果我添加
header.Typeflag = '0'

它只会压缩文件而不是目录。当它是文件或目录时,如何设置Typeflag,以便在解压缩时可以将其传递到case语句中的tar.TypeDir?
示例取自https://www.socketloop.com/tutorials/golang-archive-directory-with-tar-and-gzip
package main

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

 func checkerror(err error) {

         if err != nil {
                 fmt.Println(err)
                 os.Exit(1)
         }
 }

 func main() {

         flag.Parse() // get the arguments from command line

         destinationfile := flag.Arg(0)

         if destinationfile == "" {
                 fmt.Println("Usage : gotar destinationfile.tar.gz source")
                 os.Exit(1)
         }

         sourcedir := flag.Arg(1)

         if sourcedir == "" {
                 fmt.Println("Usage : gotar destinationfile.tar.gz source-directory")
                 os.Exit(1)
         }

         dir, err := os.Open(sourcedir)

         checkerror(err)

         defer dir.Close()

         files, err := dir.Readdir(0) // grab the files list

         checkerror(err)

         tarfile, err := os.Create(destinationfile)

         checkerror(err)

         defer tarfile.Close()
         var fileWriter io.WriteCloser = tarfile

         if strings.HasSuffix(destinationfile, ".gz") {
                 fileWriter = gzip.NewWriter(tarfile) // add a gzip filter
                 defer fileWriter.Close()            // if user add .gz in the destination filename
         }

         tarfileWriter := tar.NewWriter(fileWriter)
         defer tarfileWriter.Close()

         for _, fileInfo := range files {

                 if fileInfo.IsDir() {
                    continue
                 }

                 // see https://www.socketloop.com/tutorials/go-file-path-independent-of-operating-system

                 file, err := os.Open(dir.Name() + string(filepath.Separator) + fileInfo.Name())

                 checkerror(err)

                 defer file.Close()


                 // prepare the tar header

                 header := new(tar.Header)
                 header.Name = file.Name()
                 header.Size = fileInfo.Size()
                 header.Mode = int64(fileInfo.Mode())
                 header.ModTime = fileInfo.ModTime()


                 err = tarfileWriter.WriteHeader(header)

                 checkerror(err)

                 _, err = io.Copy(tarfileWriter, file)

                 checkerror(err)
         }

 }

当然,你应该使用 header.Typeflag = tar.TypeRegheader.Typeflag = tar.TypeDir 而不是 header.Typeflag = '0'header.Typeflag = '5'(仅在你需要与 tar.FileInfoHeader 不同的东西时才这样做)。 - Dave C
1个回答

1
如果文件在磁盘上,那么这部分已经完成。请查看FileInfoHeader。根据资源(在您的情况下为目录或文件)可以推断出Typeflag。有关可用选项的完整列表,请参阅tar标准文档

我知道这一点,但如果我传递0表示文件或5表示目录,在tar文件时不确定如何设置它。 - Tim
@Tim,我相信sberry的意思是你不应该从头开始构建tar.Header(即不要使用header:= new(tar.Header)),而是从header,err:= tar.FileInfoHeader(fileInfo,name)开始(其中name类似于您的path.Join(dir.Name(),fileInfo.Name())),然后仅更改未为您填充或要覆盖的字段。 - Dave C
1
我认为这有所帮助,但我仍然遇到问题 叹气。显然它也没有遍历隐藏目录。 - Tim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接