使用compress/gzip和archive/tar如何创建压缩的tar归档文件?

huangapple go评论74阅读模式
英文:

How to create a compressed tar archives using compress/gzip and archive/tar?

问题

我正在尝试使用Go标准库中的compress/gzip和archive/tar来创建一个压缩的tar存档。我可以成功地创建一个tar存档,但是当我尝试压缩该存档时,生成的tarball无法解压缩。在OSX上,我得到了"Error 1 - Operation Not Permitted"的错误。

要运行这段代码,你需要在同一目录下有一个名为foo.txt的文件。

package main

import (
	"archive/tar"
	"bytes"
	"compress/gzip"
	"io/ioutil"
	"log"
	"os"
)

func main() {
	var b bytes.Buffer

	// 创建一个新的zip存档。
	w := tar.NewWriter(gzip.NewWriter(&b))

	fi, err := os.Stat("foo.txt")

	if err != nil {
		log.Fatal(err)
	}

	header, err := tar.FileInfoHeader(fi, "")

	if err != nil {
		log.Fatal(err)
	}

	err = w.WriteHeader(header)

	if err != nil {
		log.Fatal(err)
	}

	contents, err := ioutil.ReadFile("foo.txt")

	if err != nil {
		log.Fatal(err)
	}

	_, err = w.Write(contents)

	if err != nil {
		log.Fatal(err)
	}

	err = w.Close()

	// 确保在Close时检查错误。
	err = ioutil.WriteFile("foo.tar.gz", b.Bytes(), 0666)

	if err != nil {
		log.Fatal(err)
	}
}

希望这可以帮助到你!

英文:

I'm attempting to create a compressed tar archive using the Go standard library, specifically compress/gzip and archive/tar. I can successfully create a tar archive, but when I try to compress said archive, the resulting tarball can't be decompressed. On OSX, I get "Error 1 - Operation Not Permitted"

To run this code, you'll need a file named foo.txt in the same directory.

package main

import (
	"archive/tar"
	"bytes"
	"compress/gzip"
	"io/ioutil"
	"log"
	"os"
)

func main() {
	var b bytes.Buffer

	// Create a new zip archive.
	w := tar.NewWriter(gzip.NewWriter(&b))

	fi, err := os.Stat("foo.txt")

	if err != nil {
		log.Fatal(err)
	}

	header, err := tar.FileInfoHeader(fi, "")

	if err != nil {
		log.Fatal(err)
	}

	err = w.WriteHeader(header)

	if err != nil {
		log.Fatal(err)
	}

	contents, err := ioutil.ReadFile("foo.txt")

	if err != nil {
		log.Fatal(err)
	}

	_, err = w.Write(contents)

	if err != nil {
		log.Fatal(err)
	}

	err = w.Close()

	// Make sure to check the error on Close.
	err = ioutil.WriteFile("foo.tar.gz", b.Bytes(), 0666)

	if err != nil {
		log.Fatal(err)
	}
}

答案1

得分: 6

你需要关闭底层的gzip写入器,以确保所有字节都被刷新到文件中。像这样:

    // gzip写入器
    gz := gzip.NewWriter(f)

    // 创建一个新的tar归档
    w := tar.NewWriter(gz)

    // 向tar归档中添加内容
    // ...

    // 确保gzip写入器刷新所有待处理的字节
    if err = gz.Close(); err != nil {
            log.Fatal(err)
    }
英文:

You need to close the underlying gzip writer so that it you are guaranteed all bytes are flushed out to the file. Like so:

    // gzip writer
    gz := gzip.NewWriter(f)

    // Create a new tar archive.
    w := tar.NewWriter(gz)

    // add things to the tar archive
    // ...

    // make sure the gzip writer flushes any pending bytes
    if err = gz.Close(); err != nil {
            log.Fatal(err)
    }

huangapple
  • 本文由 发表于 2013年12月9日 06:09:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/20459793.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定