101 lines
1.9 KiB
Go
101 lines
1.9 KiB
Go
|
package compress
|
||
|
|
||
|
import (
|
||
|
"archive/zip"
|
||
|
"bytes"
|
||
|
"io"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
)
|
||
|
|
||
|
// UnzipFromFile 解压压缩文件
|
||
|
// @params dst string 解压后目标路径
|
||
|
// @params src string 压缩文件目标路径
|
||
|
func UnzipFromFile(dst, src string) error {
|
||
|
// 打开压缩文件
|
||
|
zr, err := zip.OpenReader(filepath.Clean(src))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer func() {
|
||
|
_ = zr.Close()
|
||
|
}()
|
||
|
|
||
|
// 解压
|
||
|
return Unzip(dst, &zr.Reader)
|
||
|
}
|
||
|
|
||
|
// UnzipFromBytes 解压压缩字节流
|
||
|
// @params dst string 解压后目标路径
|
||
|
// @params src []byte 压缩字节流
|
||
|
func UnzipFromBytes(dst string, src []byte) error {
|
||
|
// 通过字节流创建zip的Reader对象
|
||
|
zr, err := zip.NewReader(bytes.NewReader(src), int64(len(src)))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// 解压
|
||
|
return Unzip(dst, zr)
|
||
|
}
|
||
|
|
||
|
// Unzip 解压压缩文件
|
||
|
// @params dst string 解压后的目标路径
|
||
|
// @params src *zip.Reader 压缩文件可读流
|
||
|
func Unzip(dst string, src *zip.Reader) error {
|
||
|
// 强制转换一遍目录
|
||
|
dst = filepath.Clean(dst)
|
||
|
// 遍历压缩文件
|
||
|
for _, file := range src.File {
|
||
|
// 在闭包中完成以下操作可以及时释放文件句柄
|
||
|
err := func() error {
|
||
|
// 跳过文件夹
|
||
|
if file.Mode().IsDir() {
|
||
|
return nil
|
||
|
}
|
||
|
// 配置输出目标路径
|
||
|
filename := filepath.Join(dst, file.Name)
|
||
|
// 创建目标路径所在文件夹
|
||
|
e := os.MkdirAll(filepath.Dir(filename), os.ModeDir)
|
||
|
if e != nil {
|
||
|
return e
|
||
|
}
|
||
|
|
||
|
// 打开这个压缩文件
|
||
|
zfr, e := file.Open()
|
||
|
if e != nil {
|
||
|
return e
|
||
|
}
|
||
|
defer func() {
|
||
|
_ = zfr.Close()
|
||
|
}()
|
||
|
|
||
|
// 创建目标文件
|
||
|
fw, e := os.Create(filename)
|
||
|
if e != nil {
|
||
|
return e
|
||
|
}
|
||
|
defer func() {
|
||
|
_ = fw.Close()
|
||
|
}()
|
||
|
|
||
|
// 执行拷贝
|
||
|
_, e = io.Copy(fw, zfr)
|
||
|
if e != nil {
|
||
|
return e
|
||
|
}
|
||
|
|
||
|
// 拷贝成功
|
||
|
return nil
|
||
|
}()
|
||
|
|
||
|
// 是否发生异常
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 解压完成
|
||
|
return nil
|
||
|
}
|