首页 > 解决方案 > 如何使用命令行解压缩 Go compress/gzip 包生成的文件?

问题描述

compress/gzip我有一个使用 Go包生成的文件,其代码如下

payload := bytes.NewBuffer(nil)
gw := gzip.NewWriter(payload)
tw := tar.NewWriter(gw)
...
tw.Close()
gw.Close()

如何从 Mac 上的命令行解压缩此文件?我试过gunzip但失败了

$ gunzip test.gz
gunzip: test.gz: not in gzip format

也尝试过没有运气

$ tar -xvf test.gz
tar: Unrecognized archive format
tar: Error exit delayed from previous errors.

标签: go

解决方案


您的问题是,在您的示例代码中,您永远不会写信给您的 tar 编写器。为了生成包含内容的有效 targz 文件,您需要记住:

  • 添加至少一个文件需要在 tarball 中
  • 每个文件都需要标头

您需要使用tar.WriteHeader为每个文件创建标头,然后您可以通过调用tar.Write将文件的内容简单地写入字节。

tar -xvf test.tgz然后,您可以使用前面示例中提到的方法解压它。

为了演示,我在机器上快速编写了一个示例代码:

package main

import (
    "compress/gzip"
    "archive/tar"
    "os"
    "fmt"
    "time"
)

func main() {
    // Create targz file which will contain other files.
    file, err := os.Create("test.tgz")
    if err != nil {
        panic(err)
    }

    gw := gzip.NewWriter(file)
    defer gw.Close()

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

    // Create file(s) in targz
    if err := addFile(tw, "myfile.test", "example content"); err != nil {
        panic(err)
    }
}

func addFile(tw *tar.Writer, fileName, content string) error {
    header := &tar.Header{
        Name:    fileName,
        Size:    int64(len(content)),
        Mode:    0655,
        ModTime: time.Now(),
    }

    err := tw.WriteHeader(header)
    if err != nil {
        return fmt.Errorf("could not write header for file %q: %w", fileName, err)
    }

    _, err = tw.Write([]byte(content))
    if err != nil {
        return fmt.Errorf("could not write content for file %q: %w", fileName, err)
    }

    return nil
}

结果如下:

$> go run main.go

$> ls -la
total 5
drwxr-xr-x  12 ullaakut  staff   384 Feb 12 05:34 ./
drwxr-xr-x  29 ullaakut  staff   928 Jan 28 14:56 ../
-rw-r--r--@  1 ullaakut  staff  6148 Dec 25 13:01 .DS_Store
-rw-r--r--   1 ullaakut  staff   888 Feb 12 05:34 main.go
-rw-r--r--   1 ullaakut  staff   121 Feb 12 05:34 test.tgz

$> tar -zxvf test.tgz
x myfile.test

$> cat myfile.test
example content

如您所见,存档被提取和解压缩就好了:)


推荐阅读