The archive/zip can't support gbk filename on chinese windows.
This is a simple test (test-gbk-zip.go):
// only for go1.4
// Go output on Chinese Win7/64bit
// go run test-gbk-zip.go
//
// File name(%s): ����/���¶���.txt
// File name(%q): "\xc0\xee\xb0\xd7/\xd4\xc2\xcf¶\xc0\xd7\xc3.txt"
// File name(%s): �Ÿ�/
// File name(%q): "\xb6Ÿ\xa6/"
//
// 7z output on Chinese Win7/64bit
//
// 7z l -r 中文-测试.zip
//
// 7-Zip [64] 9.25 alpha Copyright (c) 1999-2011 Igor Pavlov 2011-09-16
//
// Listing archive: 中文-测试.zip
//
// --
// Path = 中文-测试.zip
// Type = zip
// Physical Size = 483
//
// Date Time Attr Size Compressed Name
// ------------------- ----- ------------ ------------ ------------------------
// ..... 282 228 李白\月下独酌.txt
// D.... 0 5 杜甫
// ------------------- ----- ------------ ------------ ------------------------
// 282 233 1 files, 1 folders
package main
import (
"archive/zip"
"fmt"
"log"
"os"
"golang.org/x/text/encoding/simplifiedchinese"
)
type ZipTest struct {
Name string
File []ZipTestFile
}
type ZipTestFile struct {
Name string
Body string
}
func main() {
makeGbkTestfile()
r, err := zip.OpenReader(gbkZipTest.Name)
if err != nil {
log.Fatal(err)
}
defer r.Close()
for _, f := range r.File {
fmt.Printf("File name(%%s): %s\n", f.Name)
fmt.Printf("File name(%%q): %q\n", f.Name)
}
}
func makeGbkTestfile() {
file, err := os.Create(gbkZipTest.Name)
if err != nil {
log.Fatal(err)
}
defer file.Close()
wzip := zip.NewWriter(file)
defer func() {
if err := wzip.Close(); err != nil {
log.Fatal(err)
}
}()
for _, file := range gbkZipTest.File {
localGbkName, _ := utf8ToGBK(file.Name) // 文件名转换为 GBK编码
f, err := wzip.Create(localGbkName)
if err != nil {
log.Fatal(err)
}
_, err = f.Write([]byte(file.Body))
if err != nil {
log.Fatal(err)
}
}
}
func utf8ToGBK(text string) (string, error) {
dst := make([]byte, len(text)*2)
tr := simplifiedchinese.GB18030.NewEncoder()
nDst, _, err := tr.Transform(dst, []byte(text), true)
if err != nil {
return text, err
}
return string(dst[:nDst]), nil
}
var gbkZipTest = ZipTest{
Name: "中文-测试.zip",
File: []ZipTestFile{
{
Name: "李白/月下独酌.txt",
Body: `月下独酌 - 李白
花间一壶酒,独酌无相亲。
举杯邀明月,对影成三人。
月既不解饮,影徒随我身。
暂伴月将影,行乐须及春。
我歌月徘徊,我舞影零乱。
醒时同交欢,醉后各分散。
永结无情游,相期邈云汉。
`,
},
{
Name: "杜甫/",
Body: "",
},
},
}
So i create CL9381 try to fix this poblem.
But CL9381 can only support utf8 encoding,
it can't create local gbk encoding zip.
I think we need new api for user defined filename encoding:
func OpenReaderEx(name string, decoder func(x string)(utf8Name string)) (*ReadCloser, error)
func (w *Writer) CreateEx(name string, encoder func(x string)(localName string)) (io.Writer, error)
If the decoder or encoder is nil, the local encoding is utf8.
The func (w *Writer) Create(name string) (io.Writer, error) force use utf8 encoding.
The
archive/zipcan't support gbk filename on chinese windows.This is a simple test (
test-gbk-zip.go):So i create CL9381 try to fix this poblem.
But CL9381 can only support utf8 encoding,
it can't create local gbk encoding zip.
I think we need new api for user defined filename encoding:
If the
decoderorencoderisnil, the local encoding isutf8.The
func (w *Writer) Create(name string) (io.Writer, error)force use utf8 encoding.