dongqin5604 2017-04-12 07:59
浏览 29
已采纳

如何在压缩文件的同时获取tar中文件的所需路径

I have been using this code to write to a tar file. I am calling it like err = retarIt(dirTopDebug, path), where dirTopDebug is the path to my tar file (/tmp/abc.tar), and path is the path of files I want to add (/tmp/xyz/...). When I am untarring the generated tar file, I find that inside abc.tar files are put in /tmp/xyz/.. format. But I want them inside tar like xyz/..., i.e. without the tmp folder.

How can I do that?

func TarGzWrite(_path string, tw *tar.Writer, fi os.FileInfo) {
    fr, _ := os.Open(_path)
    //handleError(err)
    defer fr.Close()

    h := new(tar.Header)
    h.Name = _path
    h.Size = fi.Size()
    h.Mode = int64(fi.Mode())
    h.ModTime = fi.ModTime()

    err := tw.WriteHeader(h)
    if err != nil {
        panic(err)
    }

    _, _ = io.Copy(tw, fr)
    //handleError( err )
}

func IterDirectory(dirPath string, tw *tar.Writer) {
    dir, _ := os.Open(dirPath)
    //handleError( err )
    defer dir.Close()
    fis, _ := dir.Readdir(0)
    //handleError( err )
    for _, fi := range fis {
        fmt.Println(dirPath)
        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 retarIt(outFilePath, inPath string) error {
    fw, err := os.Create(outFilePath)
    if err != nil {
            return err
    }
    defer fw.Close()
    gw := gzip.NewWriter(fw)
    defer gw.Close()

    // tar write
    tw := tar.NewWriter(gw)
    defer tw.Close()

    IterDirectory(inPath, tw)
    fmt.Println("tar.gz ok")
    return nil
}
  • 写回答

1条回答 默认 最新

  • doufeinai6081 2017-04-12 10:24
    关注

    Whatever name is specified in the tar header, is used. Use the strings.LastIndex (or strings.Index) function of the strings package to separate the part till /tmp.

    So if the code in TarGzWrite function above is modified as follows it works the way you want (note: you may want to replace strings.LastIndex below with strings.Index).

    //TarGzWrite function same as above....
    h := new(tar.Header)
    //New code after this..
    lastIndex := strings.LastIndex(_path, "/tmp")
    fmt.Println("String is ", _path, "Last index is", lastIndex)
    var name string
    if lastIndex > 0 {
        name = _path[lastIndex+len("/tmp")+1:]
        fmt.Println("Got name:", name)
    } else {
        //This would not be needed, but was there just for testing my code
        name = _path
    }
    // h.Name = _path
    h.Name = name
    h.Size = fi.Size()
    h.Mode = int64(fi.Mode())
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog