Files
photography/backend-old/internal/utils/file.go
xujiang 010fe2a8c7
Some checks failed
部署后端服务 / 🧪 测试后端 (push) Failing after 5m8s
部署后端服务 / 🚀 构建并部署 (push) Has been skipped
部署后端服务 / 🔄 回滚部署 (push) Has been skipped
fix
2025-07-10 18:09:11 +08:00

172 lines
3.8 KiB
Go

package utils
import (
"crypto/md5"
"crypto/sha256"
"fmt"
"io"
"mime"
"os"
"path/filepath"
"strings"
"time"
)
// GetFileExtension 获取文件扩展名
func GetFileExtension(filename string) string {
return strings.ToLower(filepath.Ext(filename))
}
// GetMimeType 根据文件扩展名获取MIME类型
func GetMimeType(filename string) string {
ext := GetFileExtension(filename)
mimeType := mime.TypeByExtension(ext)
if mimeType == "" {
return "application/octet-stream"
}
return mimeType
}
// IsImageFile 检查是否为图片文件
func IsImageFile(filename string) bool {
imageExtensions := []string{".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".tiff"}
ext := GetFileExtension(filename)
for _, imageExt := range imageExtensions {
if ext == imageExt {
return true
}
}
return false
}
// GenerateUniqueFilename 生成唯一的文件名
func GenerateUniqueFilename(originalFilename string) string {
ext := GetFileExtension(originalFilename)
timestamp := time.Now().Unix()
randomStr := GenerateRandomString(8)
return fmt.Sprintf("%d_%s%s", timestamp, randomStr, ext)
}
// GenerateFilePath 生成文件路径
func GenerateFilePath(baseDir, subDir, filename string) string {
// 按日期组织文件夹
now := time.Now()
dateDir := now.Format("2006/01/02")
if subDir != "" {
return filepath.Join(baseDir, subDir, dateDir, filename)
}
return filepath.Join(baseDir, dateDir, filename)
}
// EnsureDir 确保目录存在
func EnsureDir(dirPath string) error {
return os.MkdirAll(dirPath, 0755)
}
// FileExists 检查文件是否存在
func FileExists(filepath string) bool {
_, err := os.Stat(filepath)
return !os.IsNotExist(err)
}
// GetFileSize 获取文件大小
func GetFileSize(filepath string) (int64, error) {
info, err := os.Stat(filepath)
if err != nil {
return 0, err
}
return info.Size(), nil
}
// CalculateFileMD5 计算文件MD5哈希
func CalculateFileMD5(filepath string) (string, error) {
file, err := os.Open(filepath)
if err != nil {
return "", err
}
defer file.Close()
hash := md5.New()
if _, err := io.Copy(hash, file); err != nil {
return "", err
}
return fmt.Sprintf("%x", hash.Sum(nil)), nil
}
// CalculateFileSHA256 计算文件SHA256哈希
func CalculateFileSHA256(filepath string) (string, error) {
file, err := os.Open(filepath)
if err != nil {
return "", err
}
defer file.Close()
hash := sha256.New()
if _, err := io.Copy(hash, file); err != nil {
return "", err
}
return fmt.Sprintf("%x", hash.Sum(nil)), nil
}
// CopyFile 复制文件
func CopyFile(src, dst string) error {
sourceFile, err := os.Open(src)
if err != nil {
return err
}
defer sourceFile.Close()
// 确保目标目录存在
if err := EnsureDir(filepath.Dir(dst)); err != nil {
return err
}
destFile, err := os.Create(dst)
if err != nil {
return err
}
defer destFile.Close()
_, err = io.Copy(destFile, sourceFile)
return err
}
// DeleteFile 删除文件
func DeleteFile(filepath string) error {
if !FileExists(filepath) {
return nil // 文件不存在,认为删除成功
}
return os.Remove(filepath)
}
// FormatFileSize 格式化文件大小为人类可读格式
func FormatFileSize(bytes int64) string {
const unit = 1024
if bytes < unit {
return fmt.Sprintf("%d B", bytes)
}
div, exp := int64(unit), 0
for n := bytes / unit; n >= unit; n /= unit {
div *= unit
exp++
}
units := []string{"KB", "MB", "GB", "TB", "PB"}
return fmt.Sprintf("%.1f %s", float64(bytes)/float64(div), units[exp])
}
// GetImageDimensions 获取图片尺寸(需要额外的图片处理库)
// 这里只是占位符,实际实现需要使用如 github.com/disintegration/imaging 等库
func GetImageDimensions(filepath string) (width, height int, err error) {
// TODO: 实现图片尺寸获取
// 需要添加图片处理依赖
return 0, 0, fmt.Errorf("not implemented")
}