英文:
How to get desired path for the files inside tar while tarring them up
问题
我一直在使用这段代码来写入一个tar文件。我像这样调用它:err = retarIt(dirTopDebug, path)
,其中dirTopDebug
是我的tar文件的路径(/tmp/abc.tar
),path
是我想要添加的文件的路径(/tmp/xyz/...
)。当我解压生成的tar文件时,我发现文件被放在/tmp/xyz/..
的格式中。但是我希望它们在tar文件中的位置是xyz/...
,即没有tmp
文件夹。
我该如何做到这一点?
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\n", 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
}
以上是你提供的代码。要将文件放在tar文件中的xyz/...
位置,而不是/tmp/xyz/..
,你可以在TarGzWrite
函数中修改h.Name
的值。将h.Name
设置为fi.Name()
即可。修改后的代码如下:
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 = fi.Name() // 修改这里
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 )
}
通过这样的修改,文件将以xyz/...
的形式放入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\n", 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
得分: 1
无论tar头中指定了什么名称,都会被使用。使用strings包中的strings.LastIndex(或strings.Index)函数来分离到/tmp为止的部分。
因此,如果上面的TarGzWrite函数的代码修改如下,它将按照您的要求工作(注意:您可能需要将strings.LastIndex替换为strings.Index)。
//TarGzWrite函数与上面相同...
h := new(tar.Header)
//此后是新代码...
lastIndex := strings.LastIndex(_path, "/tmp")
fmt.Println("字符串是", _path, "最后索引是", lastIndex)
var name string
if lastIndex > 0 {
name = _path[lastIndex+len("/tmp")+1:]
fmt.Println("得到的名称:", name)
} else {
//这不是必需的,但只是为了测试我的代码而存在
name = _path
}
// h.Name = _path
h.Name = name
h.Size = fi.Size()
h.Mode = int64(fi.Mode())
英文:
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())
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论