dongqing344716 2012-11-28 17:36
浏览 73
已采纳

如何将目录(不仅仅是其中的文件)写入golang中的tar.gz文件

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
", 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" )
    }
  • 写回答

2条回答 默认 最新

  • doupingmao1903 2012-11-28 18:22
    关注

    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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件