最近有个需求,需要写个脚本,但要编译为exe可执行文件,首先考虑python打包,奈何使用pyinstaller打包后,出现各种各样的运行错误,最后放弃了,改为golang重写。因为要用到创建和解压zip文件,golang中使用zip模块的功能,远没有python那么方便。

一、压缩部分

把文件或者文件夹压缩为zip文件,主要过程就是创建目的zip文件,然后遍历源目录,将源目录下的文件拷贝到目的zip文件中,最重要的2个方法:

1、zip.newWriter  创建一个向zip文件中写入的writer

2、writer.CreateHeader 向zip文件头中写入内容

其过程网上一搜一大把,雷同的很多,果然大家都是代码的搬运工。在网上看到用的最多的一例,见原文连接:https://blog.csdn.net/lengyuezuixue/article/details/79651549,

import ("archive/zip""fmt""io""os""strings"
)//压缩文件
//files 文件数组,可以是不同dir下的文件或者文件夹
//dest 压缩文件存放地址
func Compress(files []*os.File, dest string) error {d, _ := os.Create(dest)defer d.Close()w := zip.NewWriter(d)defer w.Close()for _, file := range files {err := compress(file, "", w)if err != nil {return err}}return nil
}func compress(file *os.File, prefix string, zw *zip.Writer) error {info, err := file.Stat()if err != nil {return err}if info.IsDir() {prefix = prefix + "/" + info.Name()fileInfos, err := file.Readdir(-1)if err != nil {return err}for _, fi := range fileInfos {f, err := os.Open(file.Name() + "/" + fi.Name())if err != nil {return err}err = compress(f, prefix, zw)if err != nil {return err}}} else {header, err := zip.FileInfoHeader(info)header.Name = prefix + "/" + header.Nameif err != nil {return err}writer, err := zw.CreateHeader(header)if err != nil {return err}_, err = io.Copy(writer, file)file.Close()if err != nil {return err}}return nil
}

以上代码Compress方法在大多数情况下没有问题,但有一个缺陷,不能压缩空目录,源目录中含有空目录及嵌套的空目录,都不能被压缩。仔细读一遍代码可知,以上代码是通过递归遍历源目录中的文件,然后将文件copy到目的zip中,第57行。但没有考虑到空目录的情况,从第31行,IsDir后,对空目录没有做任何处理导致空目录被跳过。实例运行如图:

可以看到对空目录,以上代码没有进行处理。像将其优化,增加对非空目录的处理,完整如下:

import ("archive/zip""fmt""io""os""strings"
)//压缩文件
//src 可以是不同dir下的文件或者文件夹
//dest 压缩文件存放地址
func Compress(src string, dest string) error {f, err := os.Open(src)if err != nil {return err}files := []*os.File{f}d, _ := os.Create(dest)defer d.Close()w := zip.NewWriter(d)defer w.Close()for _, file := range files {err := compress(file, "", w)if err != nil {return err}}return nil
}func compress(file *os.File, prefix string, zw *zip.Writer) error {info, err := file.Stat()if err != nil {return err}if info.IsDir() {prefix = prefix + "/" + info.Name()fileInfos, err := file.Readdir(-1)if err != nil {return err}// 增加对空目录的判断if len(fileInfos) <= 0 {header, err := zip.FileInfoHeader(info)header.Name = prefixif err != nil {fmt.Println("error is:"+err.Error())return err}_, err = zw.CreateHeader(header)if err != nil {fmt.Println("create error is:"+err.Error())return err}file.Close()}for _, fi := range fileInfos {f, err := os.Open(file.Name() + "/" + fi.Name())if err != nil {return err}err = compress(f, prefix, zw)if err != nil {return err}}} else {header, err := zip.FileInfoHeader(info)header.Name = prefix + "/" + header.Nameif err != nil {return err}writer, err := zw.CreateHeader(header)if err != nil {return err}_, err = io.Copy(writer, file)file.Close()if err != nil {return err}}return nil
}//解压
func DeCompress(zipFile, dest string) error {reader, err := zip.OpenReader(zipFile)if err != nil {return err}defer reader.Close()for _, file := range reader.File {rc, err := file.Open()if err != nil {return err}defer rc.Close()filename := dest + file.Nameerr = os.MkdirAll(getDir(filename), 0755)if err != nil {return err}w, err := os.Create(filename)if err != nil {return err}defer w.Close()_, err = io.Copy(w, rc)if err != nil {return err}w.Close()rc.Close()}return nil
}func getDir(path string) string {return subString(path, 0, strings.LastIndex(path, "/"))
}func subString(str string, start, end int) string {rs := []rune(str)length := len(rs)if start < 0 || start > length {panic("start is wrong")}if end < start || end > length {panic("end is wrong")}return string(rs[start:end])
}

在43行-56行增加了对空目录的处理,直接将目录名写入到zip header中。可以完美解决空目录不处理的问题。

golang zip压缩/解压缩用法相关推荐

  1. Java原生Zip压缩/解压缩工具类

    转载原文: 写了一个系列,写的很好,强烈推荐去看! Java压缩技术(二) ZIP压缩--Java原生实现 Java压缩技术(三) ZIP解压缩--Java原生实现 Zip压缩/解压缩工具类 缺点: ...

  2. Zip压缩/解压缩工具类

    package com.customcode.util; import java.io.*;import java.util.ArrayList; import java.util.List; imp ...

  3. Golang zip 压缩与解压

    文章目录 1.压缩 2.解压缩 3.进一步封装 3.1 压缩 3.2 解压 3.3 go-huge-util 参考文献 Go 和许多其他编程语言一样,支持从标准库中直接进行 zip 文件的压缩和解压. ...

  4. c#zip压缩解压缩全解

    全栈工程师开发手册 (作者:栾鹏) c#教程全解 c#实现文件或文件夹的zip格式的压缩解压缩. 需要引入ICSharpCode.SharpZipLib.dll链接库,下载 测试代码 static v ...

  5. Qt 之 QuaZIP(zip 压缩/解压缩)

    简述 QuaZIP是使用Qt/C++对ZLIB进行简单封装的用于压缩及解压缩ZIP的开源库.适用于多种平台,利用它可以很方便的将单个或多个文件打包为zip文件,且打包后的zip文件可以通过其它工具打开 ...

  6. Zip压缩解压缩之C++实现。

    压缩:可压缩单一文件,也可压缩文件夹里的多个文件(包括文件夹里面的子文件夹).压缩的目标文件格式无限制:demo文件使用的是.text,.h,.cpp,.png,.bmp,.wav,.mp4等. 解压 ...

  7. JAVA实现zip压缩/解压缩

    JAVA实现了I/O数据流与网络数据流的单一接口,因此数据的压缩.网络传输和解压缩的实现比较容易,下面介绍利用ZipEntry.ZipInputStream和ZipOutputStream三个Java ...

  8. zip:命令行下zip压缩/解压缩

    在Ubuntu 18.04下验证,造冰箱的大熊猫@cnblogs 2019/6/6 1 压缩单个文件 zip package.zip file 2 压缩多个文件 zip package.zip fil ...

  9. Linux下的zip压缩解压缩文件夹

    实例:压缩服务器上当前目录的内容为xxx.zip文件 zip -r xxx.zip ./* 解压zip文件到当前目录 unzip filename.zip ====================== ...

最新文章

  1. 总结 20 个开发细节
  2. 成为技术领导者——解决问题的有机方法
  3. 常见的面试思考题(MARK)
  4. 李宏毅深度学习——Backpropagation
  5. Rus入门到放弃——字符串与字符切片
  6. Android学习笔记36:使用SQLite方式存储数据
  7. 批量获取远程计算机MAC
  8. ssm影城项目_影场与属性访问器界面
  9. 前端学习(2342):react的生命周期
  10. 2021年90后脱发调研报告
  11. 【华为云技术分享】如何设计高质量软件-领域驱动设计DDD(Domain-Driven Design)学习心得
  12. Netty之四种常用 IO 模型
  13. 电脑显示已连接网络但是无internet访问
  14. php实现一键截取全屏代码,截全屏电脑快捷键是什么
  15. 《查理·芒格的100个思维模型》
  16. 程序化生成(PCG)算法的改进——基于以地学为主的多基础学科
  17. 【PaddleHub模型贡献】一行代码实现海洋生物识别
  18. 试用了40+款日记APP,才知道好软件有多难求...
  19. 微信小程序体验评分问题
  20. 【高精度】高精度除以高精度 C++题解

热门文章

  1. 计算机网络期末考试知识点汇总
  2. VC6.0编译出错Compiling...,Error spawning cl.exe的解决方法
  3. uniapp使用u-collapse的优化策略
  4. php老师把毕生的功力,为了表现雨下的凶残程度,网友都使出了毕生的功力
  5. 关于大商创安装默认数据清空说明
  6. Python直男作死篇:生日蛋糕小游戏
  7. Win10桌面图标显示不正常,变为白色
  8. 中国机器博弈事业开拓者、CAAI 会士徐心和教授因病逝世...
  9. 只读事务是否做无用功?
  10. 4 变量、作用域与内存