问题
最近在某个场景中,需要使用 go 官方的 archive/zip 处理 zip 压缩包,在处理过程中,遇到了一个问题: go 解压后的文件存在文件名乱码的情况。
解决
我们知道在 go 中,字符串是以 UTF-8 编码的,所以有可能出现乱码的情况。
我们只要在处理压缩包中的文件时,通过判断 Flags 字段,如果 Flags 为 0 , 则使用本地编码,默认为 GBK。 如果为 1 , 则使用 UTF-8 编码。
我们只要在为 0 时对文件名进行处理就好。 代码:
func Unzip(zipFile string, destDir string) error {
zipReader, err := zip.OpenReader(zipFile)
if err != nil {
return err
}
defer zipReader.Close()
var decodeName string
for _, f := range zipReader.File {
if f.Flags == 0{
i:= bytes.NewReader([]byte(f.Name))
decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder())
content,_:= ioutil.ReadAll(decoder)
decodeName = string(content)
}else{
decodeName = f.Name
}
fpath := filepath.Join(destDir, decodeName)
if f.FileInfo().IsDir() {
os.MkdirAll(fpath, os.ModePerm)
} else {
if err = os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil {
return err
}
inFile, err := f.Open()
if err != nil {
return err
}
defer inFile.Close()
outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return err
}
defer outFile.Close()
_, err = io.Copy(outFile, inFile)
if err != nil {
return err
}
}
}
return nil
}