Golang zipで中国語コードが文字化けした場合の対処方法

PHPz
リリース: 2023-04-24 15:21:56
オリジナル
766 人が閲覧しました

Golang 言語の人気に伴い、新しいアプリケーションの開発に Golang 言語を使用する人が増えています。一般的なアプリケーションの 1 つは、ファイル システムからファイルをパックし、ZIP ファイルに圧縮することです。特に中国語のファイル名を扱う場合、文字化けの問題が発生しやすくなります。この記事では、Golang zipで中国語が文字化けする問題を解決する方法について説明します。

1. 問題の内容

Golang の zip パッケージを使用する場合、処理されるファイル名に漢字が含まれる場合、ZIP ファイルに出力すると文字化けが発生します。以下の図は、中国語のファイル名を含むディレクトリ構造を示しています。

example
├── file1.txt
└── 文件2.txt
ログイン後にコピー

次のコードを使用して、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
}
ログイン後にコピー

このプログラムを実行すると、example.zip ファイルが生成されます。圧縮ファイルを開くと、ファイル名が文字化けしていることがわかります。以下の図に示すように:

Golang zipで中国語コードが文字化けした場合の対処方法

これは、プログラムが zipWriter.CreateHeader (ヘッダー) を実行するときに、ファイル名の処理にデフォルトで UTF-8 エンコーディングが使用されるためです。 , ただし、使用されるファイル名はシステムのデフォルトのエンコーディング(私の場合はGBK)です。そのため、ZIPファイルを書き込むと文字化けしてしまいます。

2. 解決策

上記の問題を解決するには、ZIP ファイルを書き込む前にファイル名が UTF-8 エンコードに変換されていることを確認する必要があります。ただし、ファイル名はシステムのデフォルトのエンコーディングを使用して生成される場合があるため、ファイル名のエンコーディング形式が正しく識別され、UTF-8 エンコーディングに変換されていることを確認する必要があります。

以下は、上記の手順を実装する方法を示す簡単な例です:

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
}
ログイン後にコピー

上記のコードでは、 golang.org/x/text/transform パッケージを使用してファイル名を変換します。 GBK 形式から UTF-8 形式で。まずパッケージをインポートし、toUTF8() 関数を通じてファイル名を GBK から UTF-8 エンコーディングに変換します。次に、addFileToZip() 関数で、変換されたファイル名で Header.Name を更新し、ZIP ファイルに追加します。

このプログラムを実行して生成される ZIP ファイルは、通常は中国語で表示されるファイル名になります。

概要

Golang zip パッケージを使用する場合、中国語のファイル名があると、ZIP ファイルに出力するときに文字化けが発生します。この問題を解決するには、文字化けを避けるために、まずファイル名を UTF-8 エンコーディングに変換する必要があります。この記事では、 golang.org/x/text/transform パッケージを使用して、ファイル名を GBK 形式から UTF-8 形式に変換しました。こうすることで、ZIP ファイルに追加するときにファイル名が文字化けしないようにすることができます。

以上がGolang zipで中国語コードが文字化けした場合の対処方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート