Maison >développement back-end >Golang >Comment gérer le code chinois tronqué dans Golang Zip
Avec la popularité du langage Golang, de plus en plus de personnes commencent à l'utiliser pour développer de nouvelles applications. L'une des applications courantes consiste à regrouper les fichiers du système de fichiers et à les compresser dans un fichier ZIP. Surtout lorsqu'il s'agit de noms de fichiers chinois, il est facile de rencontrer le problème des caractères tronqués. Cet article explique comment résoudre le problème des caractères chinois tronqués dans Golang zip.
1. Description du problème
Lors de l'utilisation du package zip de Golang, si le nom du fichier traité contient des caractères chinois, des caractères tronqués apparaîtront lors de la sortie dans le fichier ZIP. L'image ci-dessous montre une structure de répertoires contenant des noms de fichiers chinois :
example ├── file1.txt └── 文件2.txt
Nous utilisons le code suivant pour le conditionner dans un fichier ZIP :
package main import ( "archive/zip" "os" "path/filepath" ) func main() { zipFileName := "example.zip" files := []string{"example/file1.txt", "example/文件2.txt"} // Create a new ZIP file. zipFile, err := os.Create(zipFileName) if err != nil { panic(err) } defer zipFile.Close() // Create a new writer to write to the ZIP file. zipWriter := zip.NewWriter(zipFile) defer zipWriter.Close() // Iterate over the files and add them to the ZIP file. for _, file := range files { addFileToZip(file, zipWriter) } } func addFileToZip(file string, zipWriter *zip.Writer) error { // Open the file to be added to the ZIP file. fileToZip, err := os.Open(file) if err != nil { return err } defer fileToZip.Close() // Get the file information for the file being added. fileInfo, err := fileToZip.Stat() if err != nil { return err } // Create a new file header for the file being added. header, err := zip.FileInfoHeader(fileInfo) if err != nil { return err } // Set the name for the file being added (this is what appears in the ZIP archive). header.Name = filepath.Base(file) // Add the file header to the ZIP archive. writer, err := zipWriter.CreateHeader(header) if err != nil { return err } // Copy the contents of the file into the ZIP archive. _, err = io.Copy(writer, fileToZip) if err != nil { return err } return nil }
L'exécution de ce programme générera le fichier exemple.zip, ouvrez le fichier compressé, nous pouvons voir Le nom du fichier est tronqué. Comme le montre la figure ci-dessous :
En effet, lorsque le programme exécute zipWriter.CreateHeader(header), il utilisera l'encodage UTF-8 par défaut pour traiter le nom de fichier, mais le nom de fichier utilise l'encodage par défaut du système. (dans mon cas GBK au milieu). Par conséquent, il est tronqué lors de l’écriture du fichier ZIP.
2. Solution
Afin de résoudre le problème ci-dessus, nous devons nous assurer que le nom du fichier est converti en codage UTF-8 avant d'écrire le fichier ZIP. Cependant, le nom de fichier peut être généré en utilisant le codage par défaut du système, nous devons donc nous assurer que le format de codage du nom de fichier est correctement identifié et converti en codage UTF-8.
Ce qui suit est un exemple simple montrant comment mettre en œuvre les étapes ci-dessus :
package main import ( "archive/zip" "bytes" "io" "os" "path/filepath" "golang.org/x/text/encoding/simplifiedchinese" "golang.org/x/text/transform" ) func main() { zipFileName := "example.zip" files := []string{"example/file1.txt", "example/文件2.txt"} // Create a new ZIP file. zipFile, err := os.Create(zipFileName) if err != nil { panic(err) } defer zipFile.Close() // Create a new writer to write to the ZIP file. zipWriter := zip.NewWriter(zipFile) defer zipWriter.Close() // Iterate over the files and add them to the ZIP file. for _, file := range files { addFileToZip(file, zipWriter) } } func addFileToZip(file string, zipWriter *zip.Writer) error { // Open the file to be added to the ZIP file. fileToZip, err := os.Open(file) if err != nil { return err } defer fileToZip.Close() // Get the file information for the file being added. fileInfo, err := fileToZip.Stat() if err != nil { return err } // Create a new file header for the file being added. header, err := zip.FileInfoHeader(fileInfo) if err != nil { return err } // Convert the file name to UTF-8. header.Name, err = toUTF8(fileInfo.Name()) if err != nil { return err } // Add the file header to the ZIP archive. writer, err := zipWriter.CreateHeader(header) if err != nil { return err } // Copy the contents of the file into the ZIP archive. _, err = io.Copy(writer, fileToZip) if err != nil { return err } return nil } func toUTF8(src string) (string, error) { var ( buf bytes.Buffer w = transform.NewWriter(&buf, simplifiedchinese.GBK.NewDecoder()) ) _, err := w.Write([]byte(src)) if err != nil { return "", err } err = w.Close() if err != nil { return "", err } return buf.String(), nil }
Dans le code ci-dessus, nous utilisons le package golang.org/x/text/transform pour convertir le nom de fichier du format GBK au format UTF-8. . Nous importons d’abord le package et convertissons le nom de fichier de l’encodage GBK en UTF-8 via la fonction toUTF8(). Ensuite, dans la fonction addFileToZip(), nous mettons à jour Header.Name avec le nom du fichier converti et l'ajoutons au fichier ZIP.
Exécutez le fichier ZIP généré par ce programme et le nom du fichier s'affichera normalement en chinois.
Résumé
Lors de l'utilisation du package zip Golang, s'il existe un nom de fichier chinois, vous rencontrerez des caractères tronqués lors de la sortie vers le fichier ZIP. Pour résoudre ce problème, nous devons d'abord convertir le nom du fichier en codage UTF-8 pour éviter les caractères tronqués. Dans cet article, nous avons utilisé le package golang.org/x/text/transform pour convertir les noms de fichiers du format GBK au format UTF-8. De cette façon, nous pouvons garantir que le nom du fichier ne sera pas tronqué lors de son ajout au fichier ZIP.
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!