|
|
|
@ -4,13 +4,16 @@ import ( |
|
|
|
"archive/zip" |
|
|
|
"fmt" |
|
|
|
"io" |
|
|
|
"io/fs" |
|
|
|
"os" |
|
|
|
"path" |
|
|
|
"path/filepath" |
|
|
|
"strings" |
|
|
|
) |
|
|
|
|
|
|
|
/** |
|
|
|
** dirPath 目标目录 |
|
|
|
** relativeOnly:是否为相对目录 |
|
|
|
**/ |
|
|
|
// 遍历目录下的文件
|
|
|
|
func GetDirFilePaths(dirPath string, relativeOnly bool) ([]string, error) { |
|
|
|
var filePaths []string |
|
|
|
@ -154,80 +157,3 @@ func DecompressZip(zpFname string) error { |
|
|
|
} |
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
// Zip 压缩文件或目录
|
|
|
|
// @params dst io.Writer 压缩文件可写流
|
|
|
|
// @params src string 待压缩源文件/目录路径
|
|
|
|
func Zip(dst io.Writer, src string) error { |
|
|
|
// 强转一下路径
|
|
|
|
src = filepath.Clean(src) |
|
|
|
// 提取最后一个文件或目录的名称
|
|
|
|
baseFile := filepath.Base(src) |
|
|
|
// 判断src是否存在
|
|
|
|
_, err := os.Stat(src) |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
// 通文件流句柄创建一个ZIP压缩包
|
|
|
|
zw := zip.NewWriter(dst) |
|
|
|
// 延迟关闭这个压缩包
|
|
|
|
defer zw.Close() |
|
|
|
|
|
|
|
// 通过filepath封装的Walk来递归处理源路径到压缩文件中
|
|
|
|
return filepath.Walk(src, func(path string, info fs.FileInfo, err error) error { |
|
|
|
// 是否存在异常
|
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
// 通过原始文件头信息,创建zip文件头信息
|
|
|
|
zfh, err := zip.FileInfoHeader(info) |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
// 赋值默认的压缩方法,否则不压缩
|
|
|
|
zfh.Method = zip.Deflate |
|
|
|
|
|
|
|
// 移除绝对路径
|
|
|
|
tmpPath := path |
|
|
|
index := strings.Index(tmpPath, baseFile) |
|
|
|
if index > -1 { |
|
|
|
tmpPath = tmpPath[index:] |
|
|
|
} |
|
|
|
// 替换文件名,并且去除前后 "\" 或 "/"
|
|
|
|
tmpPath = strings.Trim(tmpPath, string(filepath.Separator)) |
|
|
|
// 替换一下分隔符,zip不支持 "\\"
|
|
|
|
zfh.Name = strings.ReplaceAll(tmpPath, "\\", "/") |
|
|
|
// 目录需要拼上一个 "/" ,否则会出现一个和目录一样的文件在压缩包中
|
|
|
|
if info.IsDir() { |
|
|
|
zfh.Name += "/" |
|
|
|
} |
|
|
|
|
|
|
|
// 写入文件头信息,并返回一个ZIP文件写入句柄
|
|
|
|
zfw, err := zw.CreateHeader(zfh) |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
// 仅在他是标准文件时进行文件内容写入
|
|
|
|
if zfh.Mode().IsRegular() { |
|
|
|
// 打开要压缩的文件
|
|
|
|
sfr, err := os.Open(path) |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
defer sfr.Close() |
|
|
|
|
|
|
|
// 将srcFileReader拷贝到zipFilWrite中
|
|
|
|
_, err = io.Copy(zfw, sfr) |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 搞定
|
|
|
|
return nil |
|
|
|
}) |
|
|
|
} |
|
|
|
|