Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pzip

pzip 是一个并发 ZIP 压缩与解压工具,提供命令行程序 pzippunzip,也可以作为 Go 包使用。

特性

  • 多协程支持:快速并行处理 ZIP 文件的压缩与解压
  • ZIP64 支持:处理大于 4GB 的文件及超大档案
  • 兼容 PKZIP 2.04g 版本:确保与传统 ZIP 工具的兼容性
  • 支持原生参数:兼容 zip 和 unzip 的常用命令行参数,易于集成到现有工作流中

注意:pzip 以并发方式压缩文件,不保证 ZIP 包内 entry 的顺序与输入路径或文件系统遍历顺序一致。

安装

下载二进制文件:

Releases

使用 Go 安装:

go install github.com/zdz1715/pzip/cmd/pzip@latest
go install github.com/zdz1715/pzip/cmd/punzip@latest

从源码构建:

git clone https://github.com/zdz1715/pzip.git
cd pzip
make release-snapshot

构建产物会输出到 dist/ 目录。

命令行使用

常用参数:

pzip:
  -r, --recursive          递归压缩目录
  -q, --quiet              静默模式
  -x, --exclude pattern    排除匹配条目
  -i, --include pattern    只包含匹配条目
  -z, --comment text       写入 ZIP 注释
      --strip-prefix path  去除压缩包内路径前缀
      --add-prefix path    增加压缩包内路径前缀
      --concurrency n      并发数
      --level n            压缩级别,范围 -2 到 9
      --stdlib             使用标准库 deflate
      --no-dereference     将符号链接保存为链接

punzip:
  -d, --dir path           解压目录
  -l, --list               查看文件列表
  -z, --display-comment    显示 ZIP 注释
  -q, --quiet              静默模式
  -x, --exclude pattern    排除匹配条目
  -i, --include pattern    只解压匹配条目
      --concurrency n      并发数

Go API

压缩到 ZIP 文件:

err := pzip.Compress(ctx, "archive.zip", &pzip.CompressOptions{
    Sources:     []string{"dir", "README.md"},
    Recursive:   true,
    StripPrefix: "dir",
    AddPrefix:   "release",
    Filter:      pzip.NewFilter(nil, []string{"*.log"}),
    Comment:     "release files",
})

压缩到 io.Writer

err := pzip.CompressToWriter(ctx, w, &pzip.CompressOptions{
    Sources:   []string{"dir"},
    Recursive: true,
})

解压 ZIP:

err := pzip.Extract(ctx, "archive.zip", &pzip.ExtractOptions{
    Destination: "output",
    Filter:      pzip.NewFilter([]string{"*.yaml"}, nil),
})

读取 ZIP 注释:

comment, err := pzip.Comment("archive.zip")

打开 ZIP reader:

reader, err := pzip.OpenReader("archive.zip")
if err != nil {
    return err
}
defer reader.Close()

for _, f := range reader.File {
    fmt.Println(f.Name)
}

匹配规则

过滤规则匹配 ZIP entry name,路径分隔符使用 /

示例:

*.go
dir/*
testdata/*
*.{go,md}

匹配语义兼容 Info-ZIP:*? 默认可以匹配路径分隔符 /。例如,*.go 会匹配任意目录层级中的 Go 文件。命令行中的模式需要使用引号,避免被 shell 提前展开,如 -i '*.go'

同时设置 include 和 exclude 时,条目必须匹配 include,并且不能匹配 exclude。

性能测试

以下数据来自历史测试,实际结果会受 CPU、磁盘、文件类型和并发数影响。

测试环境:

  • 操作系统:Ubuntu 20.04
  • CPU:Intel(R) Xeon(R) Gold 6254 CPU @ 3.10GHz(16 核)
  • 内存:16GB
  • 测试文件大小:23GB

SSD硬盘

压缩

使用原生zip命令:

$ time zip -r -q test-zip.zip bigdata-dir

real    14m7.312s
user    13m34.856s
sys     0m21.796s

使用pzip命令:

$ time pzip -r -q test-pzip.zip bigdata-dir

real    1m30.363s
user    3m42.956s
sys     1m10.184s

压缩效率大约提升了9.4倍,节省了89.6%时间。

解压

使用原生unzip命令:

$ time unzip -q test-zip.zip

real    2m26.580s
user    2m10.276s
sys     0m14.364s

使用punzip命令:

$ time punzip -q test-pzip.zip

real    0m28.078s
user    1m38.200s
sys     0m16.384s

解压效率大约提升了3.22倍,节省了68.9%时间。

机械硬盘

压缩

使用原生zip命令:

$ time zip -r -q test-zip.zip bigdata-dir

real    21m46.643s
user    18m25.877s
sys     1m56.902s

使用pzip命令:

$ time pzip -r -q test-pzip.zip bigdata-dir

real    6m30.449s
user    10m17.789s
sys     11m14.409s

压缩效率大约提升了3.5倍,节省了71.43%时间。

解压

使用原生unzip命令:

$ time unzip -q test-zip.zip

real    5m55.984s
user    3m36.254s
sys     1m45.136s

使用punzip命令:

$ time punzip -q test-pzip.zip

real    3m37.963s
user    4m51.073s
sys     7m9.020s

解压效率大约提升了1.64倍,节省了38.8%时间。

解决的问题:

archive/zip: zip64 extra headers problems

相关 issue:

java.util.zip: only DEFLATED entries can have EXT descriptor

相关 issue:

参考

About

高效并发的 ZIP 文件压缩与解压工具,兼容 PKZIP 2.04g 版本。

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages