是否可以在 golang 中提取 tar.xz 包?

Posted

技术标签:

【中文标题】是否可以在 golang 中提取 tar.xz 包?【英文标题】:Is it possible to extract a tar.xz package in golang? 【发布时间】:2015-01-31 08:42:05 【问题描述】:

我的理解是可以将库用于 tar 并将其发送到 xz go 库。

【问题讨论】:

【参考方案1】:

我最近创建了一个XZ decompression package,现在就是这样 可以仅使用 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()

【讨论】:

【参考方案2】:

http://golang.org/pkg/archive/tar/#example_

你也可以

import "os/exec"

cmd := exec.Command("tar", "-x", "/your/archive.tar.xz")
err := cmd.Run()

【讨论】:

这实际上并没有通过 tar 解压缩。你可能想要 tar xvJf archive.tar.xz... @Fire 它与 GNU tar 一起使用,因为 GNU tar 会自动检测压缩的存在。尽管如此,为了使该程序与不提供J 的其他tar 实现兼容,您可能希望在xz -dtar x 之间建立一个管道。另外,为什么要提供v?这不是必需的。 确实如此。 v 不是必需的。【参考方案3】:

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 抱歉,写这篇文章时我累了。现在所有错误都已修复。 我有处理焦油的代码,但这里也是golang.org/pkg/archive/tar/#example。最好让代码从 os.Open() 开始并使用上面的代码解压缩 xz 。然后,将其发送到 tar 并为每个目录/文件提取。 我的意思是,这将是未来搜索的最佳选择。 @Fire 剩下的留给读者作为练习。这并不难。

以上是关于是否可以在 golang 中提取 tar.xz 包?的主要内容,如果未能解决你的问题,请参考以下文章

在 C/C++ 中提取 tar.xz

linux怎么装后缀为tar.xz的软件安装包?

Ubuntu 18.04:无法使用单个命令提取下载的 tar.xz 文件

为 ubuntu 10.04 LTS 提取 tar.xz 和 tar.lz 的 gnutls 库文件

linux解压.tar.xz压缩包

Ubuntu .tar.xz文件解压缩命令