从Go中的tar文件中提取
此代码尝试将一些文本放入从Go中的tar文件中提取,go,gzip,tar,Go,Gzip,Tar,此代码尝试将一些文本放入tar文件中,并将其解压缩。 tar的代码工作正常,但似乎我做错了什么 因为untar同一个文件不起作用 当我用OSGUI解压我手动tar.gz的文件时,它可以工作,但是 不在这个代码中 在我看来,有两个问题 您正在使用defer关闭tar writer和gzip writer,但是只有在当前作用域结束时才延迟执行。由于您正在运行这个多功能一体的函数,所以当您尝试读取到untar时,您的文件句柄仍将打开,这可能会导致问题(例如,文件可能尚未完全刷新) 创建tarball
tar
文件中,并将其解压缩。
tar
的代码工作正常,但似乎我做错了什么
因为untar
同一个文件不起作用
当我用OSGUI解压我手动tar.gz的文件时,它可以工作,但是
不在这个代码中
在我看来,有两个问题
Typeflag
。虽然GNU tar可以处理这个问题,但假设Typeflag为“0”,Go可能不会。根据文档,常规文件的Typeflag是字节“0”。这可能意味着您需要在代码中的每个资源(目录、文件、链接等)上设置Typeflag啊哈,我现在知道2的问题了。tar的Go库用于确定标题的某些部分,如Typeflag。由于您的文件不是系统上的真正文件,因此无法填写相应的Typeflag GNUTAR显然知道如何处理这个问题,或者可能会尽最大努力解决这个问题,并且在这种情况下取得了成功
func main() {
mpath := "a.tar.gz"
// defer os.Remove(mpath)
f, err := overwrite(mpath)
defer f.Close()
if err != nil {
panic(err)
}
gw := gzip.NewWriter(f)
defer gw.Close()
if err != nil {
panic(err)
}
tw := tar.NewWriter(gw)
for _, file := range files {
hdr := &tar.Header{
Name: file.Name,
Mode: 0600,
Size: int64(len(file.Body)),
}
if err := tw.WriteHeader(hdr); err != nil {
panic(err)
}
if _, err := tw.Write([]byte(file.Body)); err != nil {
panic(err)
}
}
// Make sure to check the error on Close.
if err := tw.Close(); err != nil {
panic(err)
}
fr, err := read(mpath)
defer fr.Close()
if err != nil {
panic(err)
}
gr, err := gzip.NewReader(fr)
defer gr.Close()
if err != nil {
panic(err)
}
tr := tar.NewReader(gr)
for {
hdr, err := tr.Next()
if err == io.EOF {
// end of tar archive
break
}
if err != nil {
panic(err)
}
path := hdr.Name
switch hdr.Typeflag {
case tar.TypeDir:
if err := os.MkdirAll(path, os.FileMode(hdr.Mode)); err != nil {
panic(err)
}
case tar.TypeReg:
ow, err := overwrite(path)
defer ow.Close()
if err != nil {
panic(err)
}
if _, err := io.Copy(ow, tr); err != nil {
panic(err)
}
default:
fmt.Printf("Can't: %c, %s\n", hdr.Typeflag, path)
}
}
}