Private
Public Access
1
0
Files
u-desk/internal/filesystem/zip_helper.go

103 lines
2.8 KiB
Go
Raw 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 filesystem
import (
"archive/zip"
"fmt"
"io"
"path/filepath"
)
// ZipOperation ZIP操作回调函数类型
// 用于 withZipReader 通用包装器
type ZipOperation func(*zip.ReadCloser) (interface{}, error)
// withZipReader 通用的ZIP文件操作包装器
// 消除重复的打开/关闭逻辑,统一错误处理
// 参数:
// - zipPath: ZIP文件路径
// - operation: 操作回调函数,接收 *zip.ReadCloser返回任意结果
//
// 返回:
// - interface{}: 操作结果
// - error: 错误信息
func withZipReader(zipPath string, operation ZipOperation) (interface{}, error) {
// 1. 统一验证路径
if err := validateZipPath(zipPath); err != nil {
return nil, err
}
// 2. 打开 ZIP 文件
reader, err := zip.OpenReader(zipPath)
if err != nil {
return nil, fmt.Errorf("打开 zip 文件失败: %v", err)
}
defer reader.Close()
// 3. 执行操作
result, err := operation(reader)
if err != nil {
return nil, err
}
return result, nil
}
// withZipFile 在ZIP文件中查找特定文件并执行操作
// 进一步封装,用于处理单个文件的操作
type ZipFileOperation func(*zip.File) (interface{}, error)
// withZipFile 在ZIP中查找文件并执行操作
func withZipFile(zipPath, filePath string, operation ZipFileOperation) (interface{}, error) {
return withZipReader(zipPath, func(reader *zip.ReadCloser) (interface{}, error) {
// 查找目标文件
for _, file := range reader.File {
if isMatchFile(file, filePath) {
return operation(file)
}
}
return nil, fmt.Errorf("文件在 zip 中不存在: %s", filePath)
})
}
// isMatchFile 检查文件是否匹配目标路径
func isMatchFile(file *zip.File, targetPath string) bool {
return file.Name == targetPath ||
filepath.Clean(file.Name) == filepath.Clean(targetPath)
}
// readAllFromFile 从文件读取所有内容
// 辅助函数,避免重复的 io.ReadAll 调用
func readAllFromFile(rc io.ReadCloser) ([]byte, error) {
defer rc.Close()
return io.ReadAll(rc)
}
// getCompressionMethodString 获取压缩方法字符串描述
func getCompressionMethodString(method uint16) string {
if method == 8 {
return "Deflate"
}
return "Store"
}
// createFileInfoMap 创建文件信息map通用格式
func createFileInfoMap(file *zip.File, includeExtra ...bool) map[string]interface{} {
info := map[string]interface{}{
"name": filepath.Base(file.Name),
"path": file.Name, // zip 中的路径(已使用 /
"is_dir": file.Mode().IsDir(),
"size": file.UncompressedSize64,
"compressed": file.CompressedSize64,
"mod_time": file.Modified.Format("2006-01-02 15:04:05"),
"method": getCompressionMethodString(file.Method),
}
// 可选:额外信息
if len(includeExtra) > 0 && includeExtra[0] {
info["mode"] = file.Mode().String()
info["comment"] = file.Comment
}
return info
}