golang zip压缩/解压缩用法

news/2024/10/20 15:45:34/

最近有个需求,需要写个脚本,但要编译为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中。可以完美解决空目录不处理的问题。


http://www.ppmy.cn/news/546982.html

相关文章

C语言实现哈夫曼压缩与解压缩的实现以及读取哈夫曼编码 万文长书,绝对详细哦

哈夫曼压缩与解压缩的实现 开始之前&#xff0c;务必要看&#xff01;看了能更好的理解代码一、整体的布局二、模块功能实现1、压缩2、解压缩 三、尾记-主函数的详细介绍 开始之前&#xff0c;务必要看&#xff01;看了能更好的理解代码 为了伙伴们更好的理解我们这个代码的实…

ZLib 解压缩工具

官网&#xff1a; http://www.zlib.net/ 功能&#xff1a;压缩一段字节流&#xff0c;但是不包含任何文件信息。所以如果要编写压缩数据&#xff0c;还要自定义头部信息之类的&#xff0c;自己生成对应的文件结构 设计&#xff1a;CMake编译工具&#xff08;用于在windows中进行…

在解压缩某些文件时出现问题检查计算机上,rar文件解压缩失败解压末端出现错误的解决方法...

附件经常会是一系列的压缩文件,下载是默认文件名是一个随机数字。 因而下载完会出现压缩文件解压缩失败 解决方法:下载时重命名为带一定顺序的文件名,如文件1,文件2,文件3等 如何解决单个文件解压失败? 论坛中的许多资料都是使用RAR压缩的,上传到下载,在解压过程中可能…

解压缩文件常用命令——linux

解压缩文件常用命令——linux 解压缩文件命令1. 解压缩jar包&#xff08;1&#xff09;解压 jar&#xff08;2&#xff09;压缩 jar&#xff08;3&#xff09;部分参数说明 2.解压缩war包&#xff08;1&#xff09;解压 war&#xff08;2&#xff09;压缩 jar 3.解压缩tar包&am…

Linux之压缩解压缩

1 Linux上常见的压缩命令&#xff1a; &#xff08;1&#xff09;Linux上常见压缩文件扩展名&#xff1a; *.Z: compress程序压缩文件&#xff0c;目前使用较少。已经有gzip替换了。 *.gz: gzip程序压缩的文件。 *.bz2:bzip2程序压缩的文件&#xff0c;比gzip的压缩比更好。 无…

哈夫曼压缩与解压缩(c语言版)

目录 哈夫曼压缩与解压缩&#xff08;c语言版&#xff09; 一&#xff1a;引言 二&#xff1a;主要原理 三&#xff1a;主要技术点 四&#xff1a;实现过程 1.压缩&#xff1a; 2.解压缩&#xff1a; 五&#xff1a;详细分析&#xff0c;及代码实现 哈夫曼压缩与解压缩…

Linux账号和口令加固

1 禁用或删除无用账号 减少系统无用账号&#xff0c;降低安全风险。 操作步骤 使用命令删除不必要的账号。 userdel 使用命令锁定不必要的账号。 passwd -l 3.使用命令解锁必要的账号。 passwd -u 2 检查特殊账号 检查是否存在空口令和root权限的账号。 操作步骤 查看空…

linux解压缩命令 gz,linux的gz解压缩命令是什么

linux的gz解压缩命令&#xff1a;1、压缩文件&#xff0c;语法为【gzip 源文件】&#xff0c;压缩【b.txt】使用命令【gzip b.txt】&#xff1b;2、解压文件&#xff0c;语法为【gzip -d 压缩文件&#xff1b;gunzip 压缩文件】。 本教程操作环境&#xff1a;linux7.3系统&…