Files
kenaito-media-picker/internal/mover/mover.go
T
odboy 4da4b738e6 refactor: 按模块重构项目结构
- 删除 vars 全局状态,按职责拆分 internal/ 包:scanner/probe/classify/organize/mover/store/digest
- 数据驱动归类规则替代图片/视频重复分支,store 改为结构体实例
- build.sh 按系统类型编译:Windows 用 upx 压缩,macOS/Linux 不压缩
- 忽略目录拆分:图片_已忽略 / 视频_已忽略
- 输出构建产物加入 .gitignore
2025-03-26 21:08:12 +08:00

89 lines
2.2 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 mover 负责文件的移动,跨文件系统时自动回退为复制后删除。
package mover
import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
"github.com/redmask-hb/GoSimplePrint/goPrint"
uuid "github.com/satori/go.uuid"
)
// Mover 文件移动器
type Mover struct{}
// MoveToDir 将一批文件移动到目标目录(目标文件名使用 uuid 前缀防止同名覆盖)。
// 返回移动成功的 源路径 → 目标目录 映射,供记录去向使用。
func (m *Mover) MoveToDir(filePaths []string, targetDir string) map[string]string {
moved := make(map[string]string)
if len(filePaths) == 0 {
return moved
}
if err := os.MkdirAll(targetDir, 0755); err != nil {
fmt.Printf("=== 创建目录失败: %s, 错误: %v\n", targetDir, err)
return moved
}
bar := goPrint.NewBar(100)
bar.SetNotice("=== 移动文件到目录:")
bar.SetGraph(">")
total := len(filePaths)
for i, src := range filePaths {
if moveOne(src, targetDir) {
moved[src] = targetDir
}
bar.PrintBar(percent(i+1, total))
}
bar.PrintEnd("=== Finish")
return moved
}
// moveOne 移动单个文件;跨文件系统时 fallback 为 copy+delete
func moveOne(src, targetDir string) bool {
fileName := strings.ReplaceAll(uuid.NewV4().String(), "-", "") + "_" + filepath.Base(src)
target := filepath.Join(targetDir, fileName)
if err := os.Rename(src, target); err == nil {
return true
}
if err := copyFile(src, target); err != nil {
fmt.Printf("=== 复制文件失败, 源: %s, 目标: %s, 错误: %v\n", src, target, err)
return false
}
if err := os.Remove(src); err != nil {
fmt.Printf("=== 删除源文件失败: %s, 错误: %v\n", src, err)
// 复制成功但删除失败,文件已存在于两处,视为移动成功
}
return true
}
// copyFile 逐块复制文件
func copyFile(src, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
if _, err := io.Copy(out, in); err != nil {
return err
}
return out.Close()
}
// percent 计算百分比(0~100)
func percent(part, total int) int {
if total <= 0 {
return 100
}
return int(float64(part) / float64(total) * 100)
}