2015-08-31 2 views
2

Я не уверен, как установить Header.Typeflag при tar'ing каталоге с файлами и подкаталогами. Я знаю, добавлю ли яtar typeflag каталог или файл, когда tar'ing каталоги в golang

header.Typeflag = '0' 

Это будет только файлы tar, но не каталоги. Как установить Typeflag когда это файл или каталог, так что, когда untar'ing я могу передать его в случае заявления на 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) 
     } 

} 
+0

Конечно, вместо 'header.Typeflag = ' 0'' или 'header.Typeflag = '5'' вы должны использовать' header.Typeflag = tar.TypeReg' и 'header.Typeflag = tar.TypeDir' (и только если вы хотите/нуждаетесь в чем-то отличном от того, что [' tar .FileInfoHeader'] (https://golang.org/pkg/archive/tar/#FileInfoHeader) сделает для вас). –

ответ

1

Если файлы находятся на диск, который, по-видимому, выглядит так, то эта часть выполняется для вас. Посмотрите на FileInfoHeader. Это установит Typeflag основанный на том, что она может экстраполировать из ресурса (файла или каталога в вашем случае.)

Для получения полного списка доступных опций см the tar standard docs

+0

Мне это известно, я не уверен, как установить его во время tar'ing-файлов, если я передаю 0 для файла или 5 для каталога. – Tim

+0

@ Тит, я считаю, что ежевика говорит, что вы не должны создавать «tar.Header» с нуля (т. Е. Не использовать 'header: = new (tar.Header)'), но начинать с 'header, err: = tar.FileInfoHeader (fileInfo, name) '(где имя похоже на ваш путь .Join (dir.Name(), fileInfo.Name())), а затем меняет только поля, которые не заполняются для вас или которые вы хотите переопределить. –

+0

Я думаю, что это помогает, но у меня все еще есть проблемы * вздох *. Видимо, это тоже не идет по скрытым каталогам. – Tim

Смежные вопросы