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") }