Метод tar.Reader.Next

Метод tar.Reader.Next возвращает указатель на структуру tar.Header, содержащую информацию о следующем файле в архиве (имя, размер, права доступа, время модификации и т.д.), и одновременно продвигает внутренний указатель чтения к началу данных этого файла. Метод вызывается без параметров и возвращает два значения: указатель на заголовок и ошибку. Если достигнут конец архива, возвращается ошибка io.EOF.

Синтаксис

gofunc (tr *Reader) Next() (*Header, error)

Пример

Создадим tar-архив в памяти и последовательно прочитаем заголовки всех его файлов:

gopackage main

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

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

  headers := []string{"file1.txt", "file2.txt"}
  contents := []string{"Hello, World!", "Go is awesome"}

  for i := 0; i < len(headers); i++ {
    hdr := &tar.Header{
      Name: headers[i],
      Mode: 0o644,
      Size: int64(len(contents[i])),
    }
    if err := tw.WriteHeader(hdr); err != nil {
      panic(err)
    }
    if _, err := tw.Write([]byte(contents[i])); err != nil {
      panic(err)
    }
  }
  tw.Close()

  // Создаем Reader из буфера и читаем заголовки
  tr := tar.NewReader(&buf)
  for {
    hdr, err := tr.Next()
    if err == io.EOF {
      break
    }
    if err != nil {
      panic(err)
    }
    fmt.Printf("Name: %s, Size: %d\n", hdr.Name, hdr.Size)
  }
}

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

goName: file1.txt, Size: 13
Name: file2.txt, Size: 13

Пример

Прочитаем из архива только файлы с определенным именем и извлечем их содержимое:

gopackage main

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

func main() {
  // Подготовка архива
  var buf bytes.Buffer
  tw := tar.NewWriter(&buf)

  files := map[string]string{
    "data.txt":  "12345",
    "info.txt":  "67890",
    "ignore.me": "ignore",
  }
  for name, content := range files {
    hdr := &tar.Header{Name: name, Size: int64(len(content)), Mode: 0o644}
    tw.WriteHeader(hdr)
    tw.Write([]byte(content))
  }
  tw.Close()

  // Поиск и чтение данных
  tr := tar.NewReader(&buf)
  target := "data.txt"
  for {
    hdr, err := tr.Next()
    if err == io.EOF {
      break
    }
    if err != nil {
      panic(err)
    }
    if hdr.Name == target {
      data, _ := io.ReadAll(tr)
      fmt.Printf("%s: %s\n", target, string(data))
      break
    }
  }
}

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

godata.txt: 12345

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

  • тип tar.Header,
    который содержит метаданные файла в архиве
  • функцию tar.NewReader,
    которая создает новый Reader для чтения tar-архива
  • метод Writer.WriteHeader,
    который записывает заголовок файла при создании архива
  • пакет archive/zip,
    для работы с zip-архивами