Go如何处理zip中的中文文件名

jopen 10年前

Go的标准库已经自带了zip的库.

不过zip包在处理内部文件名时, 默认是utf8编码的.
对于Windows中文用户, 生成和读取zip内部文件名默认是GBK编码的.
因此, 在处理涉及GBK的文件名时需要做一个转换.

Go语言官方的 go.text 子标准库已经支持各种编码, 下面是utf8转GBK的函数:

import (      "code.google.com/p/go.text/encoding/simplifiedchinese"  )    func utf8ToGBK(text string) (string, error) {      dst := make([]byte, len(text)*2)      tr := simplifiedchinese.GB18030.NewEncoder()      nDst, _, err := tr.Transform(dst, []byte(text), true)      if err != nil {          return text, err      }      return string(dst[:nDst]), nil  }

在生成zip文件时, 用 utf8ToGBK 处理文件名:

func main() {      file, err := os.Create("中文-测试.zip")      if err != nil {          log.Fatal(err)      }      defer file.Close()        wzip := zip.NewWriter(file)      defer func() {          if err := wzip.Close(); err != nil {              log.Fatal(err)          }      }()        // 压缩文件      var files = []struct{ Name, Body string }{          {"11/1/readme.txt", "UTF8 字符串."},          {"11/1/readme2.txt", "This archive contains some text files."},          {"汉字/2/gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"},          {"11/中文.txt", "中文Get animal handling licence.\nWrite more examples."},          {"空目录/", ""},      }      for _, file := range files {          name, _ := utf8ToGBK(file.Name) // 文件名转换为 GBK编码          f, err := wzip.Create(name)          if err != nil {              log.Fatal(err)          }          _, err = f.Write([]byte(file.Body))          if err != nil {              log.Fatal(err)          }      }  }

这样就可以生成Windows下带简体中文的文件名压缩文件了.