Maison >développement back-end >Golang >Comment résoudre le code chinois tronqué dans Golang Zip

Comment résoudre le code chinois tronqué dans Golang Zip

爱喝马黛茶的安东尼
爱喝马黛茶的安东尼original
2019-12-10 10:36:534131parcourir

Comment résoudre le code chinois tronqué dans Golang Zip

Problème

Le package zip fourni avec le langage go peut décompresser les fichiers zip. Cependant, si vous utilisez Winrar pour le compresser en zip. Si vous utilisez go pour le décompresser à nouveau, vous constaterez que le nom du fichier est tronqué. Mais lorsque vous utilisez un certain nombre de logiciels de compression nationaux pour le compresser puis le décompresser, il ne sera pas tronqué.

Cause

Lorsque winrar est compressé, la méthode d'encodage local est utilisée par défaut pour la compression. En Chine, la méthode de codage locale est généralement GBK. Et nous savons que les chaînes du langage Go sont au format UTF-8, des caractères tronqués peuvent donc apparaître.

Comment résoudre le code chinois tronqué dans Golang Zip

Solution

Déterminez la méthode d'encodage du nom de fichier, s'il s'agit de GBK, convertissez GBK=》utf-8

D'après l'image ci-dessus, nous savons que si les 11 bits du champ flags sont 1, il s'agit d'un encodage UTF-8 et 0 est l'encodage local.

Code

Les deux packages suivants sont utilisés dans le code :

"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
}

Le site Web chinois PHP propose un grand nombre de tutoriels d'introduction au Golang gratuits, tout le monde est invité à apprendre !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:Que signifie le type Golang ?Article suivant:Que signifie le type Golang ?