Функция tar.NewReader

Функция tar.NewReader создает новый Reader для чтения данных из TAR-архива. Она принимает один параметр - интерфейс io.Reader, из которого будут читаться данные архива. Функция возвращает указатель на структуру tar.Reader, с помощью которой можно последовательно читать файлы и директории, содержащиеся в архиве.

Синтаксис

gotar.NewReader(r io.Reader) *tar.Reader

Пример

Создадим TAR-архив в памяти и прочитаем его с помощью tar.NewReader. В этом примере мы создаем архив, содержащий один файл, а затем читаем заголовок и данные этого файла:

gopackage main

import (
  "archive/tar"
  "bytes"
  "fmt"
  "io"
  "strings"
)

func main() {
  // Создаем буфер для хранения архива
  var buf bytes.Buffer

  // Создаем Writer для записи в буфер
  tw := tar.NewWriter(&buf)

  // Создаем заголовок файла
  hdr := &tar.Header{
    Name: "example.txt",
    Mode: 0600,
    Size: 11,
  }

  // Записываем заголовок
  if err := tw.WriteHeader(hdr); err != nil {
    fmt.Println("Error writing header:", err)
    return
  }

  // Записываем содержимое файла
  if _, err := tw.Write([]byte("Hello World")); err != nil {
    fmt.Println("Error writing file:", err)
    return
  }

  // Закрываем Writer
  if err := tw.Close(); err != nil {
    fmt.Println("Error closing writer:", err)
    return
  }

  // Создаем Reader для чтения архива из буфера
  tr := tar.NewReader(&buf)

  // Читаем файлы из архива
  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\n", header.Name, header.Size)

    // Читаем содержимое файла
    var content bytes.Buffer
    if _, err := io.Copy(&content, tr); err != nil {
      fmt.Println("Error reading content:", err)
      return
    }

    fmt.Printf("Content: %s\n", content.String())
  }
}

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

go"File: example.txt, Size: 11"
"Content: Hello World"

Пример

Прочитаем TAR-архив, содержащий несколько файлов и директорий. Для каждого элемента архива выведем его имя и тип:

gopackage main

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

func main() {
  // Создаем буфер с архивом
  var buf bytes.Buffer
  tw := tar.NewWriter(&buf)

  // Добавляем директорию
  hdr1 := &tar.Header{
    Name:   "docs/",
    Mode:   0755,
    Typeflag: tar.TypeDir,
  }
  tw.WriteHeader(hdr1)

  // Добавляем файл в директорию
  hdr2 := &tar.Header{
    Name: "docs/readme.txt",
    Mode: 0644,
    Size: 7,
  }
  tw.WriteHeader(hdr2)
  tw.Write([]byte("content"))

  // Добавляем файл в корень
  hdr3 := &tar.Header{
    Name: "data.txt",
    Mode: 0644,
    Size: 5,
  }
  tw.WriteHeader(hdr3)
  tw.Write([]byte("12345"))

  tw.Close()

  // Читаем архив
  tr := tar.NewReader(&buf)

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

    // Определяем тип элемента
    entryType := "file"
    if header.Typeflag == tar.TypeDir {
      entryType = "directory"
    }

    fmt.Printf("%s: %s\n", header.Name, entryType)
  }
}

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

go"docs/: directory"
"docs/readme.txt: file"
"data.txt: file"

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

  • функцию tar.NewWriter,
    которая создает писатель для TAR-архивов
  • метод tar.Reader.Next,
    который переходит к следующему файлу в архиве
  • структуру tar.Header,
    которая содержит метаданные файла в архиве
  • пакет archive/tar,
    который реализует работу с TAR-архивами