为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
函数式编程 2021-05-16 16:21:12
我想在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.txt1.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()
查看完整描述

2 回答

?
森林海

TA贡献2011条经验 获得超2个赞

一种替代方法是使用内置的filepath.Walk函数


// root_directory has been set further up


walkFn := 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

}


查看完整回答
反对 回复 2021-05-24
  • 2 回答
  • 0 关注
  • 246 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信