Пакет archive/tar

Пакет archive/tar реализует доступ к TAR-архивам в формате POSIX. Для чтения архива используется tar.Reader, который последовательно обрабатывает записи (файлы) архива. Для создания архива используется tar.Writer. Каждая запись в архиве представлена структурой tar.Header, которая содержит метаданные файла: имя, размер, права доступа и временные метки.

Чтение TAR-архива

Для чтения TAR-архива необходимо открыть файл, создать tar.Reader и последовательно вызывать метод Next для перехода к следующему файлу в архиве. Рассмотрим пример чтения всех файлов из архива:

gopackage main

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

func main() {
  file, err := os.Open("archive.tar")
  if err != nil {
    fmt.Println("Error opening archive:", err)
    return
  }
  defer file.Close()

  tr := tar.NewReader(file)

  for {
    header, err := tr.Next()
    if err == io.EOF {
      break
    }
    if err != nil {
      fmt.Println("Error reading archive:", err)
      return
    }

    fmt.Printf("File: %s, Size: %d bytes\n", header.Name, header.Size)
  }
}

Результат выполнения кода:

go"File: file1.txt, Size: 1024 bytes"
"File: file2.txt, Size: 2048 bytes"

Метод Next возвращает заголовок текущего файла и указатель на данные, которые можно прочитать с помощью методов io.Reader.

Чтение содержимого файла из TAR

После получения заголовка файла можно прочитать его содержимое с помощью ридера, возвращаемого методом Next:

gopackage main

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

func main() {
  file, err := os.Open("archive.tar")
  if err != nil {
    fmt.Println("Error opening archive:", err)
    return
  }
  defer file.Close()

  tr := tar.NewReader(file)

  header, err := tr.Next()
  if err != nil {
    fmt.Println("Error reading header:", err)
    return
  }

  data := make([]byte, header.Size)
  _, err = io.ReadFull(tr, data)
  if err != nil {
    fmt.Println("Error reading data:", err)
    return
  }

  fmt.Printf("Content of %s: %s\n", header.Name, string(data))
}

Результат выполнения кода:

go"Content of file1.txt: Hello, World!"

Обратите внимание на использование io.ReadFull для точного чтения указанного количества байт.

Создание TAR-архива

Для создания TAR-архива используется tar.Writer. Сначала создается заголовок файла с помощью tar.Header, затем заголовок записывается методом WriteHeader, после чего записываются данные файла:

gopackage main

import (
  "archive/tar"
  "os"
)

func main() {
  file, err := os.Create("new_archive.tar")
  if err != nil {
    panic(err)
  }
  defer file.Close()

  tw := tar.NewWriter(file)
  defer tw.Close()

  header := &tar.Header{
    Name: "example.txt",
    Mode: 0644,
    Size: 13,
  }

  err = tw.WriteHeader(header)
  if err != nil {
    panic(err)
  }

  _, err = tw.Write([]byte("Hello, World!"))
  if err != nil {
    panic(err)
  }
}

В результате будет создан архив new_archive.tar, содержащий один файл example.txt с содержимым Hello, World!.

Добавление нескольких файлов в TAR

Для добавления нескольких файлов в архив необходимо последовательно записывать заголовки и данные каждого файла:

gopackage main

import (
  "archive/tar"
  "os"
)

func main() {
  file, err := os.Create("multi_archive.tar")
  if err != nil {
    panic(err)
  }
  defer file.Close()

  tw := tar.NewWriter(file)
  defer tw.Close()

  files := []struct {
    name string
    data string
  }{
    {"file1.txt", "Content of file 1"},
    {"file2.txt", "Content of file 2"},
    {"file3.txt", "Content of file 3"},
  }

  for _, f := range files {
    header := &tar.Header{
      Name: f.name,
      Mode: 0644,
      Size: int64(len(f.data)),
    }

    err = tw.WriteHeader(header)
    if err != nil {
      panic(err)
    }

    _, err = tw.Write([]byte(f.data))
    if err != nil {
      panic(err)
    }
  }
}

Этот код создаст архив с тремя текстовыми файлами.

Смотрите также

  • структуру tar.Header,
    которая содержит метаданные файла в архиве
  • метод tar.Reader.Next,
    который переходит к следующему файлу в архиве
  • метод tar.Writer.WriteHeader,
    который записывает заголовок файла в архив
  • метод tar.Writer.Close,
    который завершает запись архива