go 处理zip解压时乱码问题

问题

go语言自带的zip包可以解压zip文件
然而,如果你用winrar压缩成zip后。再用go去解压会发现文件名称是乱码。
而当你使用一众国产压缩软件压缩后再解压却不是乱码。

原因

winrar压缩时,默认采用本地编码方式来进行压缩。
在中国,本地编码方式一般是GBK。

而我们知道go语言字符串都是utf-8格式的,所以有可能出现乱码的情况。

go 处理zip解压时乱码问题_第1张图片
image.png

解决方案

判定文件名编码方式,如果为GBK则转换GBK=》utf-8

由上面图片我们知道如果flags字段11bit为为1则是utf-8编码。0位本地编码

代码

代码中要用到如下两个包
"golang.org/x/text/encoding/simplifiedchinese"
"golang.org/x/text/transform"

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{
            //如果标致位是0  则是默认的本地编码   默认为gbk
            i:= bytes.NewReader([]byte(f.Name))
            decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder())
            content,_:= ioutil.ReadAll(decoder)
            decodeName = string(content)
        }else{
            //如果标志为是 1 << 11也就是 2048  则是utf-8编码
            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
}

你可能感兴趣的:(go 处理zip解压时乱码问题)