2015-01-31 4 views

ответ

2

Я недавно создана XZ decompression package так что теперь можно извлечь tar.xz используя только код Go.

Следующий код извлекает файл myfile.tar.xz к текущему каталогу:

package main 

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

    "xi2.org/x/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() 
} 
3

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

также вы можете сделать

import "os/exec" 

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

Это на самом деле не распаковывать с помощью дегтя. Вероятно, вы хотите tar xvJf archive.tar.xz ... – Fire

+0

@Fire Он работает с GNU tar, поскольку GNU tar автоматически обнаруживает наличие сжатия. Тем не менее, чтобы эта программа была совместима с другими реализациями tar, которые не предоставляют 'J', вы можете настроить канал между' xz -d' и 'tar x'. Кроме того, почему вы предоставляете 'v'? Это не требуется. – fuz

+1

Это правда. 'v' не требуется. – Fire

1

Там нет датчика Зива-Зив-Markow или декодер в стандартной библиотеке Go. Если вы позволили предположить, что платформа ваш код работает на предоставляет утилиту 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 
} 
+0

Обратите внимание, что недостаточно аргументов для возврата. – Fire

+0

Вы не используете r. – Fire

+0

@Fire Извините, я устал, когда писал это. Теперь все ошибки исправлены. – fuz

Смежные вопросы