153 lines
4.0 KiB
Go
153 lines
4.0 KiB
Go
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
|
||
}
|