4

How can I read xz files in a go program? When I try to read them using lzma, I get an error in lzma header error.

phihag
  • 278,196
  • 72
  • 453
  • 469
  • I'm guessing that this library only supports LZMA and not LZMA2 which is used by `xz` archives. – nemo Oct 24 '13 at 02:27

2 Answers2

9

You have 3 options.

  1. Try another library, perhaps one that uses cgo. I see two here.
  2. Use cgo directly/make your own lib.
  3. Use the xz executable.

Option three is easier than it sounds. Here is what I would use:

func xzReader(r io.Reader) io.ReadCloser {
    rpipe, wpipe := io.Pipe()

    cmd := exec.Command("xz", "--decompress", "--stdout")
    cmd.Stdin = r
    cmd.Stdout = wpipe

    go func() {
        err := cmd.Run()
        wpipe.CloseWithError(err)
    }()

    return rpipe
}

Runnable code here: http://play.golang.org/p/SrgZiKdv9a

Stephen Weinberg
  • 51,320
  • 14
  • 134
  • 113
  • Thanks, I somehow missed both godoc.org and this marvelously simple piping. – phihag Oct 24 '13 at 08:48
  • 1
    Your Option 3 solution is generally useful for a wide range of shell commands to be incorporated into Go programs. – Rick-777 Oct 25 '13 at 14:04
2

I recently created an XZ decompression package. It does not require Cgo. You can find it here:

https://github.com/xi2/xz

A program to decompress stdin to stdout:

package main

import (
    "io"
    "log"
    "os"

    "github.com/xi2/xz"
)

func main() {
    r, err := xz.NewReader(os.Stdin, 0)
    if err != nil {
        log.Fatal(err)
    }
    _, err = io.Copy(os.Stdout, r)
    if err != nil {
        log.Fatal(err)
    }
}
Michael Hampton
  • 9,737
  • 4
  • 55
  • 96
xi2
  • 96
  • 1
  • 2