【Go语言】Go进行 无密码zip 文件的压缩和解压以及带密码zip文件压缩和解压(详细版)

Go 和许多其他编程语言一样,支持从标准库中直接进行 zip 文件的压缩和解压。在 Go 中利用标准库包 archive/zip 完成 zip 文件的创建和提取。golang zip包的解压有官方的zip包(archive/zip),但是官方给的zip解压包代码只有解压不带密码的zip包,如果我们要解压带密码的zip就做不了, 解决方案:使用 github.com/yeka/zip

一、压缩操作

1.1 第一步:创建一个 zip 基础文件

zip 文件也是一个文件,我们要做的第一件事是创建为一个简单的文件作为 zip 文件,就像在 Go 中处理任何其他文件一样。使用 os 第三方包的 os.Create() 函数创建一个文件对象。

 func Create(name string) (*File, error)

1.2 第二步:初始化 zip.Writer

使用 archive/zip包中的 zip.NewWriter 函数初始化一个 zip.Writer,用于将数据(文件和目录)写入 zip 文件。

    func NewWriter(w io.Writer) *Writer

1.3 第三步:使用 zip.Writer.Create创建一个 io.Writer

一旦创建完 zip writer 后,便可以使用 zip.Writer.Create 向 zip 文件中添加一个文件或目录。它返回一个待压缩的文件内容应写入的 Writer,文件内容将使用 Deflate 方法进行压缩。

    func (w *Writer) Create(name string) (io.Writer, error)

1.4 第四步:使用 io.Copy或 io.Writer.Write 写数据到到 zip 文件

zip.Writer.Create 函数返回一个 io.Writer ,因此任何文件内容都可以通过流式写入该 writer。使用 io.Copy 或调用 writer 的 Write 方法。

   func Copy(dst Writer, src Reader) (written int64, err error)

1.5 第五步:使用 zip.Writer.Close 关闭 zip 文件

将所有文件和目录写入 zip 文件后,可以通过 zip.Writer.Close 方法关闭 zip writer,将所有数据写入指向基础 zip 文件的数据流。注意,它不会关闭指向基础 zip 文件的 Writer。

    func (w *Writer) Close() error

1.6 压缩无密码zip包(源码案例)

package main

import (
	"archive/zip"
	"fmt"
	"io"
	"os"
)

func main_zip_file() {
	fmt.Println("creating zip archive...")
	// 1、创建 zip 基础文件
	archive, err := os.Create("D:\\CODEFile01\\GoPro\\unZipPro\\src\\data\\archive.zip")
	if err != nil {
		panic(err)
	}
	defer archive.Close()

	// 2、初始化zip写入对象
	zipWriter := zip.NewWriter(archive)
	fmt.Println("opening first file...")
	f1, err := os.Open("D:\\CODEFile01\\GoPro\\unZipPro\\src\\data\\test.csv")
	if err != nil {
		panic(err)
	}
	defer f1.Close()
	fmt.Println("writing first file to archive...")

	// 3、使用 zip.Writer.Create 创建一个 io.Writer,使用Create() 向zip文件中添加一个文件或目录
	w1, err := zipWriter.Create("test.csv")
	if err != nil {
		panic(err)
	}

	// 4、使用 io.Copy 或 io.Writer.Write 写数据到到zip文件
	if _, err := io.Copy(w1, f1); err != nil {
		panic(err)
	}

	fmt.Println("opening second file...")
	f2, err := os.Open("D:\\CODEFile01\\GoPro\\unZipPro\\src\\data\\test.txt")
	if err != nil {
		panic(err)
	}
	defer f2.Close()

	fmt.Println("writing second file to archive...")
	w2, err := zipWriter.Create("test.txt")
	if err != nil {
		panic(err)
	}
	if _, err := io.Copy(w2, f2); err != nil {
		panic(err)
	}
	fmt.Println("closing zip archive...")

	// 5、使用 zip.Writer.Close 关闭 zip 文件
	zipWriter.Close()
}

二、解压操作

2.1 第一步:使用 zip.OpenReader 打开 zip 文件

要想解压 zip 文件我们可能需要做的第一件事是打开它。我们可以使用 archive/zip 包提供的函数 zip.OpenReader 来打开 zip 文件,以 io.ReadCloser 的形式返回一个 zip.Reader 的实例。

    func OpenReader(name string) (*ReadCloser, error)

2.2 第二步:循环访问 zip 中的文件

zip.OpenReader 返回一个 zip.Reader 实例,其包含一个 zip.File 切片。

  type Reader struct {
  	File []*File
  	Comment string
  	// contains filtered or unexported fields

2.3 第三步:使用 zip.File.Open方法读取 zip 中文件的内容

   func (f *File) Open() (io.ReadCloser, error)

2.4 第四步:使用 io.Copy 或 io.Writer.Write 保存解压后的文件内容**

   func Copy(dst Writer, src Reader) (written int64, err error)

2.5 第五步:使用 zip.Reader.Close 关闭 zip 文件**

读取完 zip 存档中所有文件的内容并保存到指定位置后,要用接口 ReadCloser 中的方法 Close 关闭文件句柄。

    type ReadCloser interface {
    	Reader
    	Closer
    }
    
    // Closer is the interface that wraps the basic Close method.
    // The behavior of Close after the first call is undefined.
    // Specific implementations may document their own behavior.
    type Closer interface {
    	Close() error
    }

2.6 解压不带密码zip压缩包(源码案例)

package main

import (
	"archive/zip"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"
)

func main() {
	dst := "D:\\CODEFile01\\GoPro\\unZipPro\\src\\data_output"
	// 1、使用zip.OpenReader打开zip文件
	archive, err := zip.OpenReader("D:\\CODEFile01\\GoPro\\unZipPro\\src\\data\\DYSH_20210104_Index.zip")
	if err != nil {
		panic(err)
	}
	defer archive.Close()

	// 2、循环访问 zip 中的文件 zip.File 切片
	for _, f := range archive.File {
		filePath := filepath.Join(dst, f.Name)
		fmt.Println("unzipping file ", filePath)

		if !strings.HasPrefix(filePath, filepath.Clean(dst)+string(os.PathSeparator)) {
			fmt.Println("invalid file path")
			return
		}
		if f.FileInfo().IsDir() {
			fmt.Println("creating directory...")
			os.MkdirAll(filePath, os.ModePerm)
			continue
		}

		if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
			panic(err)
		}

		dstFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
		if err != nil {
			panic(err)
		}

		// 3、使用 zip.File.Open 方法读取 zip 中文件的内容
		fileInArchive, err := f.Open()
		if err != nil {
			panic(err)
		}

		// 4、使用 io.Copy 或 io.Writer.Write 保存解压后的文件内容
		if _, err := io.Copy(dstFile, fileInArchive); err != nil {
			panic(err)
		}

		// 5、使用 zip.Reader.Close 关闭 zip 文件
		dstFile.Close()
		fileInArchive.Close()
	}
}

三、针对带密码的zip操作

解决方案:使用 github.com/yeka/zip

3.1 解压带密码zip压缩包

关键代码:

if f.IsEncrypted() {
	f.SetPassword(passwd)
}

其实就是将go官方zip包 archive/zip做一个替换即可。

3.2 解压带密码zip压缩包(源码案例)

package main

import (
	//"archive/zip"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"
	"github.com/yeka/zip"
)

func main() {
	dst := "D:\\CODEFile01\\GoPro\\unZipPro\\src\\data_output"
	passwd := "DataYes"
	// 1、使用zip.OpenReader打开zip文件
	archive, err := zip.OpenReader("D:\\CODEFile01\\GoPro\\unZipPro\\src\\data\\DYSH_20210104_Index.zip")
	if err != nil {
		panic(err)
	}
	defer archive.Close()

	// 2、循环访问 zip 中的文件 zip.File 切片
	for _, f := range archive.File {
		if f.IsEncrypted() {
			f.SetPassword(passwd)
		}
		filePath := filepath.Join(dst, f.Name)
		fmt.Println("unzipping file ", filePath)

		if !strings.HasPrefix(filePath, filepath.Clean(dst)+string(os.PathSeparator)) {
			fmt.Println("invalid file path")
			return
		}
		if f.FileInfo().IsDir() {
			fmt.Println("creating directory...")
			os.MkdirAll(filePath, os.ModePerm)
			continue
		}

		if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
			panic(err)
		}

		dstFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
		if err != nil {
			panic(err)
		}

		// 3、使用 zip.File.Open 方法读取 zip 中文件的内容
		fileInArchive, err := f.Open()
		if err != nil {
			panic(err)
		}

		// 4、使用 io.Copy 或 io.Writer.Write 保存解压后的文件内容
		if _, err := io.Copy(dstFile, fileInArchive); err != nil {
			panic(err)
		}

		// 5、使用 zip.Reader.Close 关闭 zip 文件
		dstFile.Close()
		fileInArchive.Close()
	}
}

以上便是针对带密码的zip压缩包解压方法!!!

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
ZArc2Go 特别是具有压缩文件格式转换功能的压缩工具。它功能全面,可以支持7-ZIP、A、ACE、ARC、ARJ、B64、BZ2、BH、CAB、BZA、CPIO、ENC、DEB、GCA、GZ、GZA、HA、JAR、LHA、LIB、LZH、MBF、MIM、PAK、PK3、RAR、RPM、TAR、TAZ、TBZ、TGZ、TZ、UUE、XXE、YZ1、Z、ZIP、ZOO等格式,支持对压缩文件进行解密。 ZArc2Go 绿色中文ZArc2Go 绿色中文 IZArc是非常好用! 要打开一个存档只需双击(或者,你工作在Web样式,点击一次),在我的电脑或Windows资源管理器中列出的档案, 拖放档案到IZArc,或使用标准打开对话框。主要IZArc窗口功能的名称列表,以及大小 在开放档案中的所有文件。 此列表可以滚动和分类上的任何领域。可配置的工具栏提供快速访问常用操作。 广泛的上下文敏感的帮助总是可用的。 拖放 Windows的拖放界面,完全支持。您可以将来自IZArc文件拖放到其他应用程序, 或者只是到Windows资源管理器解压缩到指定的目录。 IZArc将投下他们的目标应用程序之前,将文件解压缩。 目标应用程序会将这些文件,就好像他们已经被删除从我的电脑或Windows资源管理器。 您也可以删除的档案上IZArc打开它们,或者滴上IZArc文件,将其添加到一个开新的存档。 IZArc支持以下压缩文件类型: 7-ZIP,A,ACE,ARC,ARJ,B64,BH,BIN,BZ2,BZA,C2D,CDI,CAB,CPIO,DEB,ENC,GCA,GZ,GZA,HA,IMG,ISO,JAR,LHA LIB,LZH,医疗保险基金,中密度纤维板,MIM,NRG,PAK,PDI,PK3,RAR,RPM,TAR,TAZ,TBZ,TGZ,TZ,UUE,WAR,XPI,XXE,YZ1,Z,ZIP,ZOO IZArc的主要特点 >创建一个归档 >将文件添加到现有存档 >从现有的档案删除文件 >摘自现有的存档文件 >测试归档文件 >转换档案 >转换的CD图片 >修复损坏的存档 >搜索任何文件在很多档案 >收藏夹 >获取文件和信息,如压缩率,路径或大小的详细列表,存档文件 >同时支持多空8.3文件名 >磁盘往返于多个磁盘或其他可移动媒体跨越 >实施可能性的名字大小,日期等列表项排序 >全拖放支持 > CD / DVD映像支持(ISO,BIN,MDF,NRG,IMG,C2D,PDI,CDI) >集成在Windows资源管理器上下文菜单 >自动安装大多数软件的分发归档文件 >添加/查看评论在归档 >通过双击到在文件列表中的文件,它的开通与关联到这个文件类型的程序 >检查特征 >创建一个自解压存档 >电子邮件归档 >检查是否有新的更新 >内建多语言支持 >病毒扫描功能 > UU/ XX/ MIME编码/解码 >创建多卷集 >合并多卷集 > UnSFX(转换成自解压(SFX)。EXE文件到标准档案) >使用Rijandael加密文件 – AES(256位)加密 >邮编加密(WinZip的9兼容) > BZIP压缩ZIP压缩文件 >解密(.ize)文件 >使用 VirusTotal 检查档案和文件归档
gocryptfs 是一个使用 Go 开发的,加密的覆盖文件系统。gocryptfs 基于 go-fuse FUSE 库和其 LoopbackFileSystem API 构建。gocryptfs 灵感来源于 EncFS,修复了其安全问题,提供更好的性能。gocryptfs 当前只支持 Linux 系统,以后会继续支持 OS X。安装:$ go get github.com/rfjakob/gocryptfs使用:$ mkdir cipher plain $ $GOPATH/bin/gocryptfs --init cipher   [...] $ $GOPATH/bin/gocryptfs cipher plain   [...] $ echo test > plain/test.txt $ ls -l cipher   total 8   -rw-rw-r--. 1 user  user   33  7. Okt 23:23 0ao8Hyyf1A-A88sfNvkUxA==   -rw-rw-r--. 1 user  user  233  7. Okt 23:23 gocryptfs.conf $ fusermount -u plain性能:./benchmark.bash gocryptfs v0.3.1-30-gd69e0df-dirty; on-disk format 2 PASS BenchmarkStreamWrite-2       100      12246070 ns/op      85.63 MB/s BenchmarkStreamRead-2        200       9125990 ns/op     114.90 MB/s BenchmarkCreate0B-2        10000        101284 ns/op BenchmarkCreate1B-2        10000        178356 ns/op       0.01 MB/s BenchmarkCreate100B-2       5000        361014 ns/op       0.28 MB/s BenchmarkCreate4kB-2        5000        375035 ns/op      10.92 MB/s BenchmarkCreate10kB-2       3000        491071 ns/op      20.85 MB/s ok      github.com/rfjakob/gocryptfs/integration_tests  17.216s 标签:文件加密

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值