how to write a directory [not just the files in it ] to a tar.gz file in golang
go, gzip, tar
Solution
You're only adding the filename to the tar, not the entire path. You need to keep the whole path for Tar to be able to understand directories. You just need to change one line:
h.Name = fi.Name()
Should be:
h.Name = _path
On Linux, the output of `tar -tvf test.tar.gz`:
-rw-rw-r-- 0/0 0 2012-11-28 11:17 test/0.txt
-rw-rw-r-- 0/0 0 2012-11-28 11:17 test/sub/1.txt
Problem
I want to write a tar_gz tool in Go. The input is just like linux command: ``` $tar czvf targetFileName inputDirectoryPath ``` Suppose I have an inputDirectory structured as below: ``` test [dir] -- 0.txt -- 1 [sub dir] -- 1.txt ``` For Example: use command: ``` $tar czvf test.tar.gz test/ ``` we can tar and gzip the whole test directory. My Problem is I can write a tar and gz route to recursively iterate all the file in test directory and write the file to test.tar.gz file. But I don't know how to write a directory to the test.tar.gz. After running my program, the structure in test.tar.gz file is: ``` 0.txt 1.txt ``` Can anyone tell me how to write the directory recursively to the output tar.gz file. Thanks a lot. ``` package main import ( "fmt" "os" "io" "log" "strings" "archive/tar" "compress/gzip" ) func handleError( _e error ) { if _e != nil { log.Fatal( _e ) } } func TarGzWrite( _path string, tw *tar.Writer, fi os.FileInfo ) { fr, err := os.Open( _path ) handleError( err ) defer fr.Close() h := new( tar.Header ) h.Name = fi.Name() h.Size = fi.Size() h.Mode = int64( fi.Mode() ) h.ModTime = fi.ModTime() err = tw.WriteHeader( h ) handleError( err ) _, err = io.Copy( tw, fr ) handleError( err ) } func IterDirectory( dirPath string, tw *tar.Writer ) { dir, err := os.Open( dirPath ) handleError( err ) defer dir.Close() fis, err := dir.Readdir( 0 ) handleError( err ) for _, fi := range fis { curPath := dirPath + "/" + fi.Name() if fi.IsDir() { //TarGzWrite( curPath, tw, fi ) IterDirectory( curPath, tw ) } else { fmt.Printf( "adding... %s\n", curPath ) TarGzWrite( curPath, tw, fi ) } } } func TarGz( outFilePath string, inPath string ) { // file write fw, err := os.Create( outFilePath ) handleError( err ) defer fw.Close() // gzip write gw := gzip.NewWriter( fw ) defer gw.Close() // tar write tw := tar.NewWriter( gw ) defer tw.Close() IterDirectory( inPath, tw ) fmt.Println( "tar.gz ok" ) } func main() { targetFilePath := "test.tar.gz" inputDirPath := "test/" TarGz( targetFilePath, strings.TrimRight( inputDirPath, "/" ) ) fmt.Println( "Hello, World" ) } ```