Golang zip压缩及加密

package zip

import (
	"github.com/itnotebooks/zip"
	"io"
	"log"
	"os"
	"path/filepath"
	"strings"
)

// ZipLib 递归压缩,默认采用AES256加密方式加密
// 支持以下加密方式
// Standard         ZIP标准,安全性最低
// AES128           AES128位,安全性高
// AES192           AES192位,安全性高
// AES256           AES256位,安全性最高,本程序默认采用此加密方式
func ZipLib(dst, src string, encrypt bool, password, enc string) (err error) {
	var dstFileBaseName = ""

	// 创建压缩文件对象
	zfile, err := os.Create(dst)
	defer zfile.Close()

	if err != nil {
		return err
	}

	// 通过文件对象生成写入对象
	zFileWriter := zip.NewWriter(zfile)
	defer func() {
		// 检测一下是否成功关闭
		if err := zFileWriter.Close(); err != nil {
			log.Fatalln(err)
		}
	}()

	info, err := os.Stat(src)
	if err != nil {
		return err
	}

	var baseDir string
	if info.IsDir() {
		baseDir = filepath.Base(src)

		if !strings.HasSuffix(src, "/") {
			dstName := filepath.Base(dst)
			dstFileBaseName = strings.TrimSuffix(dstName, filepath.Ext(dstName))
		}
	}

	// 将文件写入 zFileWriter 对象 ,可能会有很多个目录及文件,递归处理
	return filepath.Walk(src, func(path string, fi os.FileInfo, errBack error) (err error) {
		if errBack != nil {
			return errBack
		}

		if strings.HasSuffix(path, ".zip") {
			return
		}
		//创建文件头
		header, err := zip.FileInfoHeader(fi)
		if err != nil {
			return err
		}

		if baseDir != "" {
			// 如果原目录是以"/"结尾,表示打包指定目录时不包含该目录
			if strings.HasSuffix(src, "/") {
				header.Name = strings.TrimPrefix(path, src)
			} else {
				header.Name = filepath.Join(dstFileBaseName, baseDir, strings.TrimPrefix(path, src))
			}
		}

		if fi.IsDir() {
			header.Name += "/"
		} else {
			header.Method = zip.Deflate

		}

		var fh io.Writer
		if encrypt {
			// 加密方式
			var encryption = zip.AES256Encryption

			switch enc {
			case "Standard":
				encryption = zip.StandardEncryption
			case "AES128":
				encryption = zip.AES128Encryption
			case "AES192":
				encryption = zip.AES192Encryption

			}

			// 写入文件头信息,并配置密码
			fh, err = zFileWriter.Encrypt(header, password, encryption)
		} else {
			// 写入文件头信息
			fh, err = zFileWriter.CreateHeader(header)
		}

		if err != nil {
			return err
		}

		// 判断是否是标准文件
		if !header.Mode().IsRegular() {
			return nil
		}

		// 打开要压缩的文件
		file, err := os.Open(path)
		defer file.Close()
		if err != nil {
			return
		}

		// 将文件对象拷贝到 writer 结构中
		ret, err := io.Copy(fh, file)
		if err != nil {
			return
		}

		log.Printf("added: %s, total: %d\n", path, ret)

		return nil
	})
}

调用

func TestZipLib(t *testing.T) {
	enc := "AES256"
	encrypt := true
	pass := tools.RandomString(12)
	baseDir := tools.GetBaseDir()
	ZipLib(baseDir+"/test/202309.zip", baseDir+"/target/2023-09-07/xxx.csv", encrypt, pass, enc)
	log.Println("Zip file password:", pass)
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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 标签:文件加密
Golang中,可以使用`archive/zip`包来进行zip压缩。下面是一个简单的示例代码,演示如何使用该包进行文件或目录的压缩: ```go package main import ( "archive/zip" "fmt" "io" "os" "path/filepath" ) func main() { // 要压缩的文件或目录路径 source := "/path/to/source" // 压缩后的zip文件路径 destination := "/path/to/destination.zip" err := zipFiles(destination, source) if err != nil { fmt.Println(err) } else { fmt.Println("压缩完成!") } } func zipFiles(destination string, source string) error { // 创建一个新的zip文件 zipFile, err := os.Create(destination) if err != nil { return err } defer zipFile.Close() // 创建zip.Writer,用于向zip文件中写入数据 archive := zip.NewWriter(zipFile) defer archive.Close() // 递归遍历源路径下的所有文件和目录 filepath.Walk(source, func(path string, info os.FileInfo, err error) error { if err != nil { return err } // 获取源路径下的相对路径,用于在zip文件中创建相应的目录结构 relativePath, err := filepath.Rel(source, path) if err != nil { return err } // 创建一个新的文件或目录头部 header, err := zip.FileInfoHeader(info) if err != nil { return err } // 设置头部的名称为相对路径 header.Name = relativePath if info.IsDir() { // 如果是目录,则写入一个目录头部到zip文件中 header.Name += "/" header.Method = zip.Store } else { // 如果是文件,则写入文件内容到zip文件中 header.Method = zip.Deflate } // 创建一个新的文件或目录条目,写入zip.Writer中 writer, err := archive.CreateHeader(header) if err != nil { return err } if !info.IsDir() { // 如果是文件,则打开源文件并将内容复制到zip文件中 file, err := os.Open(path) if err != nil { return err } defer file.Close() _, err = io.Copy(writer, file) if err != nil { return err } } return nil }) return nil } ``` 你可以将`source`和`destination`变量替换为你希望的路径,然后运行代码即可实现压缩。请确保你拥有对源文件或目录的读取权限,并且目标路径是一个有效的zip文件路径。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值