Пакет archive/tar
Пакет archive/tar реализует доступ к TAR-архивам в формате POSIX.
Для чтения архива используется tar.Reader, который последовательно
обрабатывает записи (файлы) архива. Для создания архива используется
tar.Writer. Каждая запись в архиве представлена структурой
tar.Header, которая содержит метаданные файла: имя, размер,
права доступа и временные метки.
Чтение TAR-архива
Для чтения TAR-архива необходимо открыть файл, создать tar.Reader
и последовательно вызывать метод Next для перехода к следующему
файлу в архиве. Рассмотрим пример чтения всех файлов из архива:
package 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)
}
}
Результат выполнения кода:
"File: file1.txt, Size: 1024 bytes"
"File: file2.txt, Size: 2048 bytes"
Метод Next возвращает заголовок текущего файла и указатель
на данные, которые можно прочитать с помощью методов io.Reader.
Чтение содержимого файла из TAR
После получения заголовка файла можно прочитать его содержимое
с помощью ридера, возвращаемого методом Next:
package 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))
}
Результат выполнения кода:
"Content of file1.txt: Hello, World!"
Обратите внимание на использование io.ReadFull для точного
чтения указанного количества байт.
Создание TAR-архива
Для создания TAR-архива используется tar.Writer.
Сначала создается заголовок файла с помощью tar.Header,
затем заголовок записывается методом WriteHeader,
после чего записываются данные файла:
package 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
Для добавления нескольких файлов в архив необходимо последовательно записывать заголовки и данные каждого файла:
package 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,
который завершает запись архива