Files
WddSuperAgent/agent-wdd/utils/ZipUtils.go
2025-03-27 16:09:20 +08:00

153 lines
4.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package utils
import (
"agent-wdd/log"
"archive/tar"
"archive/zip"
"compress/gzip"
"io"
"os"
"path/filepath"
)
// UnzipFile 解压文件, 支持zip tgz tar.gz tar
func UnzipFile(zipFile string, targetFolder string) {
log.Info("解压文件: %s, 到: %s", zipFile, targetFolder)
// 检查文件扩展名以确定解压缩方法
fileExt := filepath.Ext(zipFile)
switch fileExt {
case ".zip":
// 使用标准库中的archive/zip包进行解压缩
zipReader, err := zip.OpenReader(zipFile)
if err != nil {
log.Error("无法打开ZIP文件: %s, 错误: %s", zipFile, err.Error())
return
}
defer zipReader.Close()
// 创建目标文件夹
if err := os.MkdirAll(targetFolder, 0755); err != nil {
log.Error("无法创建目标文件夹: %s, 错误: %s", targetFolder, err.Error())
return
}
// 遍历ZIP文件中的所有文件
for _, file := range zipReader.File {
zippedFile, err := file.Open()
if err != nil {
log.Error("无法打开ZIP中的文件: %s, 错误: %s", file.Name, err.Error())
continue
}
defer zippedFile.Close()
// 构建目标文件路径
targetFilePath := filepath.Join(targetFolder, file.Name)
// 如果是目录,则创建目录
if file.FileInfo().IsDir() {
if err := os.MkdirAll(targetFilePath, file.Mode()); err != nil {
log.Error("无法创建目录: %s, 错误: %s", targetFilePath, err.Error())
continue
}
} else {
// 如果是文件,则创建文件并写入内容
if err := os.MkdirAll(filepath.Dir(targetFilePath), 0755); err != nil {
log.Error("无法创建文件的父目录: %s, 错误: %s", filepath.Dir(targetFilePath), err.Error())
continue
}
targetFile, err := os.OpenFile(targetFilePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
if err != nil {
log.Error("无法创建目标文件: %s, 错误: %s", targetFilePath, err.Error())
continue
}
defer targetFile.Close()
if _, err := io.Copy(targetFile, zippedFile); err != nil {
log.Error("无法写入文件内容: %s, 错误: %s", targetFilePath, err.Error())
continue
}
}
}
case ".tar", ".tar.gz", ".tgz":
// 使用标准库中的archive/tar包进行解压缩
var file *os.File
var err error
if fileExt == ".tar.gz" || fileExt == ".tgz" {
file, err = os.Open(zipFile)
if err != nil {
log.Error("无法打开TAR.GZ文件: %s, 错误: %s", zipFile, err.Error())
return
}
defer file.Close()
gzipReader, err := gzip.NewReader(file)
if err != nil {
log.Error("无法创建GZIP读取器: %s, 错误: %s", zipFile, err.Error())
return
}
defer gzipReader.Close()
tarReader := tar.NewReader(gzipReader)
if err := extractTar(tarReader, targetFolder); err != nil {
log.Error("解压TAR.GZ文件时出错: %s, 错误: %s", zipFile, err.Error())
return
}
} else {
file, err = os.Open(zipFile)
if err != nil {
log.Error("无法打开TAR文件: %s, 错误: %s", zipFile, err.Error())
return
}
defer file.Close()
tarReader := tar.NewReader(file)
if err := extractTar(tarReader, targetFolder); err != nil {
log.Error("解压TAR文件时出错: %s, 错误: %s", zipFile, err.Error())
return
}
}
default:
log.Error("不支持的文件类型: %s", fileExt)
return
}
}
// 辅助函数用于解压TAR文件
func extractTar(tarReader *tar.Reader, targetFolder string) error {
for {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
return err
}
targetFilePath := filepath.Join(targetFolder, header.Name)
switch header.Typeflag {
case tar.TypeDir:
if err := os.MkdirAll(targetFilePath, 0755); err != nil {
return err
}
case tar.TypeReg:
if err := os.MkdirAll(filepath.Dir(targetFilePath), 0755); err != nil {
return err
}
file, err := os.OpenFile(targetFilePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, os.FileMode(header.Mode))
if err != nil {
return err
}
defer file.Close()
if _, err := io.Copy(file, tarReader); err != nil {
return err
}
}
}
return nil
}