我有些困难,不知道如何将目录写入tarball的头信息中。例如,我有以下目录结构:
test [dir]
-- test1.txt
-- subDirA [sub dir]
-- test2.txt
如果我使用Go tar可执行文件对test进行打包,那么解压后将保留原有结构。如果在tarball上运行tar -tvf命令,则得到的列表如下:
test/test1.txt
test/subDirA/test2.txt
然而,如果我手动执行tar -cvf test命令,然后执行tar -tvf命令,列表将会是:
test/
test/test1.txt
test/subDirA/
test/subDirA/test2.txt
这是我希望我的Go打包程序也能做到的。在我的Go程序中,我尝试添加一个新的方法
writeDirToTar
来处理将目录添加到tarWriter中。我从fileWalk函数中调用writeFileToTar或writeDirToTar。当我在writeDirToTar
中调用io.Copy(tarWriter, file)
时,我会收到“test/subDirA是一个目录”的错误提示,这有点讲得通。是否有解决方法?func writeToTar(fileDir string,
sourceBase string,
tarWriter *tar.Writer,
f os.FileInfo) error {
file, err := os.Open(fileDir)
if err != nil {
log.Print("error opening file")
return err
}
defer file.Close()
// relative paths are used to preserve the directory paths in each file path
relativePath, err := filepath.Rel(sourceBase, fileDir)
tarheader := new(tar.Header)
tarheader.Name = relativePath
tarheader.Size = f.Size()
tarheader.Mode = int64(f.Mode())
tarheader.ModTime = f.ModTime()
err = tarWriter.WriteHeader(tarheader)
if err != nil {
log.Print("error writing tarHeader")
return err
}
_, err = io.Copy(tarWriter, file)
if err != nil {
log.Print("error writing to tarWriter")
return err
}
return nil
}
func writeDirToTar(fileDir string,
sourceBase string,
tarWriter *tar.Writer,
f os.FileInfo) error {
file, err := os.Open(fileDir)
if err != nil {
log.Print("error opening file")
return err
}
defer file.Close()
// relative paths are used to preserve the directory paths in each file path
relativePath, err := filepath.Rel(sourceBase, fileDir)
if tarHeader, err := tar.FileInfoHeader(f, relativePath); err != nil {
log.Print("error writing tarHeader")
return err
}
tarHeader.Name = relativePath
tarheader.Mode = int64(f.Mode())
tarheader.ModTime = f.ModTime()
_, err = io.Copy(tarWriter, file)
if err != nil {
log.Print("error writing to tarWriter")
return err
}
return nil
}