golang 压缩文件和解压文件
以下代码只是压缩单个文件,如果是目录可以先用archive/tar 包归档目录,然后压缩归档后的问天。
package main
import (
"compress/gzip"
"encoding/base64"
"fmt"
"io"
"os"
"path/filepath"
)
// 压缩文件,支持中文名
func CompressFile(src, dst string) error {
inFile, err := os.Open(src)
if err != nil {
return err
}
defer inFile.Close()
outFile, err := os.Create(dst)
if err != nil {
return err
}
defer outFile.Close()
gw := gzip.NewWriter(outFile)
defer gw.Close()
// 将中文文件名转成 base64,放在 Comment 字段
baseName := filepath.Base(src)
encodedName := base64.StdEncoding.EncodeToString([]byte(baseName))
gw.Comment = "B64FN:" + encodedName
// Header.Name 只能放 ASCII,用占位符
gw.Name = "file"
_, err = io.Copy(gw, inFile)
return err
}
// 解压文件,恢复中文名
func DecompressFile(src, dstDir string) (string, error) {
inFile, err := os.Open(src)
if err != nil {
return "", err
}
defer inFile.Close()
gr, err := gzip.NewReader(inFile)
if err != nil {
return "", err
}
defer gr.Close()
// 默认文件名
outName := gr.Name
if outName == "" {
outName = "file"
}
// 如果 Comment 有 base64 名字,就还原
if len(gr.Comment) > 5 && gr.Comment[:6] == "B64FN:" {
decoded, err := base64.StdEncoding.DecodeString(gr.Comment[6:])
if err == nil {
outName = string(decoded)
}
}
outPath := filepath.Join(dstDir, outName)
outFile, err := os.Create(outPath)
if err != nil {
return "", err
}
defer outFile.Close()
_, err = io.Copy(outFile, gr)
return outPath, err
}
func main() {
src := "测试文件.txt"
dst := "test.gz"
// 压缩
if err := CompressFile(src, dst); err != nil {
fmt.Println("压缩失败:", err)
return
}
fmt.Println("压缩成功:", dst)
// 解压
out, err := DecompressFile(dst, ".")
if err != nil {
fmt.Println("解压失败:", err)
return
}
fmt.Println("解压成功:", out)
}

浙公网安备 33010602011771号