taskExecute/pkg/compress/index.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
}