ыgolang В windows tar.gz сохраняет имена файлов кириллицы кракозябрами
Создаю файл tar.gz в windows 10 имя файла на русском, но сохраняет не пойми на каком языке... в чем может быть причина?
package main
import (
"archive/tar"
"compress/gzip"
"io"
"io/ioutil"
"log"
"os"
)
func main() {
var err error
archive, err := os.Create("puma_config" + ".tar.gz")
if err != nil {
panic(err)
}
w := gzip.NewWriter(archive)
tw := tar.NewWriter(w)
basePath := "./test/"
filesWrite, err := ioutil.ReadDir(basePath)
if err != nil {
log.Println(err)
}
for _, file := range filesWrite {
fileP := basePath + file.Name()
addToArchive(tw, fileP)
}
archive.Close()
w.Close()
tw.Close()
}
func addToArchive(tw *tar.Writer, filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
info, err := file.Stat()
if err != nil {
return err
}
log.Println(info.Name())
header, err := tar.FileInfoHeader(info, info.Name())
if err != nil {
return err
}
header.Name = info.Name()
err = tw.WriteHeader(header)
if err != nil {
return err
}
_, err = io.Copy(tw, file)
if err != nil {
return err
}
return nil
}
UPDATE
Сами названия файлов пустые из примера @Pak Uula
Ответы (1 шт):
UPDATE
Разобрался в вашем коде. У вас не в том порядке писатели закрываются.
Должно быть вот так:
tw.Close()
w.Close()
archive.Close()
Сначала закрыть поток tar, затем поток gzip и в конце закрыть собственно файл.
В результате получаем вот что:
Для проверки в вашем архиваторе прикладываю получившийся архив.
UPDATE2
Как выяснилось, не все архиваторы одинаково понимают формат TAR. Архиватор 7z не поддерживает юникодные пути в архивах. Вместо них он показывает папки PaxHeaders.nnn.
Исходный пост
Либо вьюер для архивов у вас неправильно имена показывает, либо где-то имена портятся.
Вот контрпример - программа создаёт архив из файлов с именами на кириллице. Программа получена из примера в документации минимальной переделкой. В созданном архиве должны получиться три файла с именами ридми.тхт,гофер.txt и туду.txt. Созданный архив сохраняется в файл test.tar.
package main
import (
"archive/tar"
"fmt"
"io"
"log"
"os"
)
func main() {
// Create and add some files to the archive.
f, err := os.Create("test.tar")
if err != nil {
panic(err)
}
tw := tar.NewWriter(f)
var files = []struct {
Name, Body string
}{
{"ридми.тхт", "Этот архив создан для проверки создания таров из файлов с русскими буковками."},
{"гофер.txt", "Имена Гофера:\nGeorge\nGeoffrey\nGonzo"},
{"туду.txt", "Добыть лицензию на разведение животных (придурки!)."},
}
for _, file := range files {
hdr := &tar.Header{
Name: file.Name,
Mode: 0600,
Size: int64(len(file.Body)),
}
if err := tw.WriteHeader(hdr); err != nil {
log.Fatal(err)
}
if _, err := tw.Write([]byte(file.Body)); err != nil {
log.Fatal(err)
}
}
if err := tw.Close(); err != nil {
log.Fatal(err)
}
f.Close()
f, err = os.Open("test.tar")
if err != nil {
panic(err)
}
// Open and iterate through the files in the archive.
tr := tar.NewReader(f)
for {
hdr, err := tr.Next()
if err == io.EOF {
break // End of archive
}
if err != nil {
log.Fatal(err)
}
fmt.Printf("Contents of %s:\n", hdr.Name)
if _, err := io.Copy(os.Stdout, tr); err != nil {
log.Fatal(err)
}
fmt.Println()
}
f.Close()
}
Запускаем: Windows 10, Go 1.16.4, WinRaR 6.00

Имена, как видите, сохранены.







