Tim
Tim

Reputation: 51

tar typeflag directory or file when tar'ing directories in golang

I'm not sure how to set Header.Typeflag when tar'ing a directory with files and subdirectories. I know if I add

header.Typeflag = '0'

It will only tar files but not directories. How do I set the Typeflag when it is a file or directory so when untar'ing I can pass it in a case statement to tar.TypeDir

Example taken from 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)
         }

 }

Upvotes: 3

Views: 1642

Answers (1)

sberry
sberry

Reputation: 132038

If the files are on disk, which it looks like they are, then that part is done for you. Have a look at FileInfoHeader. That will set the Typeflag based on what it can extrapolate from the resource (directory or file in your case.)

For a complete list of the available options see the tar standard docs

Upvotes: 1

Related Questions