在 golang 中是否有可能提取 tar.xz 压缩包?

6

在 Golang 中是否可以解压 tar.xz 文件?我的理解是可以使用 tar 库,并将其发送到 xz go 库进行处理。

3个回答

7

我最近创建了一个XZ解压包,现在可以仅使用Go代码提取tar.xz文件。

以下代码将myfile.tar.xz文件提取到当前目录:

package main

import (
    "archive/tar"
    "fmt"
    "io"
    "log"
    "os"

    "github.com/xi2/xz"
)

func main() {
    // Open a file
    f, err := os.Open("myfile.tar.xz")
    if err != nil {
        log.Fatal(err)
    }
    // Create an xz Reader
    r, err := xz.NewReader(f, 0)
    if err != nil {
        log.Fatal(err)
    }
    // Create a tar Reader
    tr := tar.NewReader(r)
    // Iterate through the files in the archive.
    for {
        hdr, err := tr.Next()
        if err == io.EOF {
            // end of tar archive
            break
        }
        if err != nil {
            log.Fatal(err)
        }
        switch hdr.Typeflag {
        case tar.TypeDir:
            // create a directory
            fmt.Println("creating:   " + hdr.Name)
            err = os.MkdirAll(hdr.Name, 0777)
            if err != nil {
                log.Fatal(err)
            }
        case tar.TypeReg, tar.TypeRegA:
            // write a file
            fmt.Println("extracting: " + hdr.Name)
            w, err := os.Create(hdr.Name)
            if err != nil {
                log.Fatal(err)
            }
            _, err = io.Copy(w, tr)
            if err != nil {
                log.Fatal(err)
            }
            w.Close()
        }
    }
    f.Close()
}

4

这实际上不是通过tar解压缩的。你可能想要使用tar xvJf archive.tar.xz... - Fire
@Fire,GNU tar可以自动检测压缩文件。但是,为了保持该程序与其他不提供“J”的tar实现兼容,您可能需要在“xz -d”和“tar x”之间设置管道。此外,为什么要提供“v”?这并不是必需的。 - fuz
1
没错,v 不是必需的。 - Fire

1
在Go标准库中没有Lempel-Ziv-Markow编码器或解码器。如果你可以假设你的代码运行的平台提供xz实用程序,你可以使用像这样的存根函数:
import "os/exec"

// decompress xz compressed data stream r.
func UnxzReader(r io.Reader) (io.ReadCloser, error) {
    unxz := exec.Command("xz", "-d")
    unxz.Stdin = r
    out, err := unxz.StdoutPipe()
    if err != nil {
        return nil, err
    }

    err = unxz.Start()
    if err != nil {
        return nil, err
    }

    // we are not interested in the exit status, but we should really collect
    // that zombie process
    go unxz.Wait()

    return out, nil
}

参数不足,无法返回。 - Fire
@Fire 抱歉,我写这个时有点累了。现在所有的漏洞都已经修复了。 - fuz
我有处理tar文件的代码,但这里也有http://golang.org/pkg/archive/tar/#example。为了完整性,最好编写从os.Open()开始并使用上述代码解压缩xz的代码。然后,将其发送到tar,并提取每个目录/文件。 - Fire
这对于未来的搜索来说是最好的,我的意思是。 - Fire
@Fire 其余部分留给读者自己练习。这并不是很难。 - fuz
对于未来的读者,请注意,xz -d -T0 使用计算机的所有线程进行解压缩。 - Fire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接