Loading... ## 前言 碰到了需要golang进行压缩文件夹的操作,在网上搜索到的压缩代码大多都一样,如下所示 ```go // Zip 打包成zip文件 func Zip(filesDir string, zipPath string) { // 预防:旧文件无法覆盖 os.RemoveAll(zipPath) // 创建:zip文件 zipfile, _ := os.Create(zipPath) defer zipfile.Close() // 打开:zip文件 archive := zip.NewWriter(zipfile) defer archive.Close() // 遍历路径信息 filepath.Walk(filesDir, func(path string, info os.FileInfo, _ error) error { // 如果是源路径,提前进行下一个遍历 if path == filesDir { return nil } // 获取:文件头信息 header, _ := zip.FileInfoHeader(info) header.Name = strings.TrimPrefix(path, filesDir+`\`) // 判断:文件是不是文件夹 if info.IsDir() { header.Name += `/` } else { // 设置:zip的文件压缩算法 header.Method = zip.Deflate } // 创建:压缩包头部信息 writer, _ := archive.CreateHeader(header) if !info.IsDir() { file, _ := os.Open(path) defer file.Close() io.Copy(writer, file) } return nil }) } ``` 运行后发现,他会将源文件的路径带入到压缩包内,并创建很多层路径文件夹,排查代码后发现,问题出在第24行 ```go header.Name = strings.TrimPrefix(path, filesDir+`\`) ``` ## 压缩代码 这一行的作用是将源文件的路径去掉前面压缩路径的部分,但是他用的符号是"\\",而linux下的文件路径符号是"/",也就是该代码仅适用于win平台,进行改良后,能兼容win,linux双平台下的代码如下 ```#go // Zip 打包成zip文件 func Zip(filesDir string, zipPath string) { sysType := runtime.GOOS if sysType == "windows" { // windows系统 统一路径符号为"\" filesDir = strings.ReplaceAll(filesDir, "/", "\\") } // 预防:旧文件无法覆盖 os.RemoveAll(zipPath) // 创建:zip文件 zipfile, _ := os.Create(zipPath) defer zipfile.Close() // 打开:zip文件 archive := zip.NewWriter(zipfile) defer archive.Close() // 遍历路径信息 filepath.Walk(filesDir, func(path string, info os.FileInfo, _ error) error { // 如果是源路径,提前进行下一个遍历 if path == filesDir { return nil } // 获取:文件头信息 header, _ := zip.FileInfoHeader(info) if sysType == "windows" { header.Name = strings.TrimPrefix(path, filesDir+`\`) } else { header.Name = strings.TrimPrefix(path, filesDir+`/`) } // 判断:文件是不是文件夹 if info.IsDir() { header.Name += `/` } else { // 设置:zip的文件压缩算法 header.Method = zip.Deflate } // 创建:压缩包头部信息 writer, _ := archive.CreateHeader(header) if !info.IsDir() { file, _ := os.Open(path) defer file.Close() io.Copy(writer, file) } return nil }) } ``` ## 解压代码 另外附上解压文件的代码 ```go // Unzip 解压文件 func Unzip(zipPath, dstDir string) error { // 打开压缩包 reader, err := zip.OpenReader(zipPath) if err != nil { return err } defer reader.Close() for _, file := range reader.File { if err := unzipFile(file, dstDir); err != nil { return err } } return nil } func unzipFile(file *zip.File, dstDir string) error { // 创建文件目录 filePath := path.Join(dstDir, file.Name) if file.FileInfo().IsDir() { if err := os.MkdirAll(filePath, os.ModePerm); err != nil { return err } return nil } if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil { return err } // 读取文件内容 rc, err := file.Open() if err != nil { return err } defer rc.Close() // 创建空文件 w, err := os.Create(filePath) if err != nil { return err } defer w.Close() // 保存文件内容 _, err = io.Copy(w, rc) return err } ``` 最后修改:2023 年 06 月 02 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,请随意打赏