feat: 扫描整理支持中止;存放目录始终创建 KMP已整理 层

This commit is contained in:
2025-05-31 21:09:26 +08:00
parent 0aa9d44025
commit ea88f3e766
6 changed files with 157 additions and 32 deletions
+20 -5
View File
@@ -7,6 +7,7 @@
package scanner
import (
"context"
"fmt"
"os"
"path/filepath"
@@ -38,11 +39,12 @@ type Result struct {
// Options 扫描的参数。
type Options struct {
RootDir string // 从哪个目录开始扫
SkipDir string // 这个目录整个跳过(整理输出目录,不能把自己整理的成果又扫一遍)
SkipDirNames []string // 名字叫这些的目录跳过(比如任意位置的「KMP已整理」)
SkipNames []string // 名字叫这些的文件跳过(数据库文件、ffprobe 程序等)
OnProgress func(done, total int) // 每处理完一些文件就报一次进度
Ctx context.Context // 中止信号:ctx 被取消时扫描立即停下(可为 nil)
RootDir string // 从哪个目录开始扫
SkipDir string // 这个目录整个跳过(整理输出目录,不能把自己整理的成果又扫一遍)
SkipDirNames []string // 名字叫这些的目录跳过(比如任意位置的「KMP已整理」)
SkipNames []string // 名字叫这些的文件跳过(数据库文件、ffprobe 程序等)
OnProgress func(done, total int) // 每处理完一些文件就报一次进度
}
// Scan 从根目录开始递归扫描,找出所有文件并识别每个文件的 MIME 类型。
@@ -58,6 +60,10 @@ func Scan(opts Options) (*Result, error) {
walkCount := 0
lastReport := time.Now()
err := filepath.Walk(opts.RootDir, func(currentPath string, info os.FileInfo, err error) error {
// 用户点了中止:立刻停下来,不继续翻目录
if opts.Ctx != nil && opts.Ctx.Err() != nil {
return opts.Ctx.Err()
}
if err != nil {
// 某个文件夹打不开(没权限/坏了)不影响大局,警告一声跳过它继续扫
fmt.Printf("=== 扫描跳过(无法访问): %s, 错误: %v\n", currentPath, err)
@@ -126,6 +132,11 @@ func Scan(opts Options) (*Result, error) {
go func() {
defer wg.Done()
for i := range jobs {
// 用户点了中止:不再认类型,但还要继续把通道里的任务消费完,
// 否则发任务的主 goroutine 会一直堵在发送上
if opts.Ctx != nil && opts.Ctx.Err() != nil {
continue
}
res.Files[i].Mime = detectMime(res.Files[i].Path)
if opts.OnProgress != nil {
opts.OnProgress(int(atomic.AddInt32(&done, 1)), total)
@@ -138,6 +149,10 @@ func Scan(opts Options) (*Result, error) {
}
close(jobs)
wg.Wait()
// 中止时把"已取消"当错误带回去,好让上层识别成"已中止"而不是正常完成
if opts.Ctx != nil && opts.Ctx.Err() != nil {
return res, opts.Ctx.Err()
}
return res, nil
}