创建使用Go的存档Unicode文件名zip存档/ ZIP
package main
import (
"archive/zip"
"fmt"
"io"
"os"
"path/filepath"
"strings"
)
func main() {
var (
Path = os.Args[1]
Name = os.Args[2]
)
File, _ := os.Create(Name)
PS := strings.Split(Path, "\\")
PathName := strings.Join(PS[:len(PS)-1], "\\")
os.Chdir(PathName)
Path = PS[len(PS)-1]
defer File.Close()
Zip := zip.NewWriter(File)
defer Zip.Close()
walk := func(Path string, info os.FileInfo, err error) error {
if err != nil {
fmt.Println(err)
return err
}
if info.IsDir() {
return nil
}
Src, _ := os.Open(Path)
defer Src.Close()
fmt.Println(Path)
FileName, _ := Zip.Create(Path)
io.Copy(FileName, Src)
Zip.Flush()
return nil
}
if err := filepath.Walk(Path, walk); err != nil {
fmt.Println(err)
}
}
这MYDIR路径:创建使用Go的存档Unicode文件名zip存档/ ZIP
-----root
|---2015-05(dir)
|---中文.go
|---package(dir)
|---你好.go
当我使用此代码目录,中国会出现乱码。谁可以帮我解决问题。
的问题是,默认情况下在压缩条目名称只有ASCII字符由Zip specification,更明确允许的:(来源:APPENDIX D)
附录D.1 ZIP格式历来支持只有原始IBM PC字符 编码集(通常称为IBM代码页437)。这限制将 文件名字符存储为仅限于原始MS-DOS范围值 内的那些字符,并且不能正确支持其他字符编码中的文件名,或 语言。为了解决这个限制,这个规范将支持 下面的变化。
后来增加了对Unicode名称的支持。这可以打上一个特殊位被称为general purpose bit 11
,也叫Language encoding flag (EFS)
:
第4.4.4节 - 通用标志位 - 第11位 - 语言编码标志(EFS)。如果这个位被设置,这个文件的文件名和注释字段必须使用UTF-8编码。
附录D.2如果未设置通用位11,则文件名和注释应符合原始ZIP字符编码的 。如果设置了通用第11位,则 文件名和注释必须使用由UTF-8存储 规范定义的字符编码格式支持Unicode标准,版本4.1.0或 。 Unicode标准由Unicode 联盟(www.unicode.org)发布。存储在ZIP文件 内的UTF-8编码数据预计不包含字节顺序标记(BOM)。
的general purpose bit flag
存在并且支持转到:它是FileHeader
结构的Flags
字段。不幸的是,Go没有设置这个位的方法,默认情况下它是0.
所以添加对Unicode名称支持的最简单的方法是简单地将bit 11
设置为1。
h := &zip.FileHeader{Name:Path, Method: zip.Deflate, Flags: 0x800}
FileName, _ := Zip.CreateHeader(h)
第一行创建一个FileHeader
其中0x800
(bit 11
)值设置为Flags
现场告诉该文件的名称将被编码:用相反的
FileName, _ := Zip.Create(Path)
启动ZIP条目使用UTF-8
(这是Go在将string
写入io.Writer
时执行的操作)。
注:
这样,UTF-8的文件名会被保留,但不是所有的拉链读/提取支持它。例如,在Windows上,Windows文件处理程序,Windows资源管理器不会将其解码为UTF-8,但例如更严重的Zip处理程序(例如SecureZip)将会看到UTF-8文件名并且将正确提取文件名使用UTF-8解码)。
package main
import (
"archive/zip"
"fmt"
"io"
"os"
"path/filepath"
"strings"
)
func main() {
var (
Path = os.Args[1]
Name = os.Args[2]
)
File, _ := os.Create(Name)
PS := strings.Split(Path, "\\")
PathName := strings.Join(PS[:len(PS)-1], "\\")
os.Chdir(PathName)
Path = PS[len(PS)-1]
defer File.Close()
Zip := zip.NewWriter(File)
defer Zip.Close()
walk := func(Path string, info os.FileInfo, err error) error {
if err != nil {
fmt.Println(err)
return err
}
if info.IsDir() {
return nil
}
Src, _ := os.Open(Path)
defer Src.Close()
//FileName, _ := Zip.Create(Path)
h := &zip.FileHeader{Name: Path, Method: zip.Deflate, Flags: 0x800}
FileName, _ := Zip.CreateHeader(h)
io.Copy(FileName, Src)
Zip.Flush()
return nil
}
if err := filepath.Walk(Path, walk); err != nil {
fmt.Println(err)
}
}
如果您可以添加关于如何解决问题的解释将会很有帮助。 – Carpetsmoker