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

我想在Go中编写一个tar_gz工具。输入就像linux命令:


$tar czvf targetFileName inputDirectoryPath

假设我的inputDirectory结构如下:


test [dir]

-- 0.txt

    -- 1 [sub dir]

         -- 1.txt

例如:使用命令:


$tar czvf test.tar.gz test/

我们可以tar和gzip整个测试目录。



我的问题是我可以编写tar和gz路由来递归地迭代测试目录中的所有文件,并将该文件写入test.tar.gz文件。但是我不知道如何将目录写入test.tar.gz。运行程序后,test.tar.gz文件中的结构为:


0.txt

1.txt

谁能告诉我如何将目录递归写入输出tar.gz文件。非常感谢。


    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()

函数式编程
浏览 247回答 2
2回答

森林海

一种替代方法是使用内置的filepath.Walk函数// root_directory has been set further upwalkFn := func(path string, info os.FileInfo, err error) error {    if info.Mode().IsDir() {        return nil    }    // Because of scoping we can reference the external root_directory variable    new_path := path[len(root_directory):]    if len(new_path) == 0 {        return nil    }    fr, err := os.Open(path)    if err != nil {        return err    }    defer fr.Close()    if h, err := tar.FileInfoHeader(info, new_path); err != nil {        log.Fatalln(err)    } else {        h.Name = new_path        if err = tw.WriteHeader(h); err != nil {            log.Fatalln(err)        }    }    if length, err := io.Copy( tw, fr ); err != nil {        log.Fatalln(err)    } else {        fmt.Println(length)    }    return nil}if err = filepath.Walk(root_directory, walkFn); err != nil {    return err}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go