Files
kenaito-media-picker/bug20260813.md
T
odboy f5e3f6b4ef fix: 修复媒体整理中的文件覆盖、BMP解析与重复整理问题
- 移动文件改用 uuid+原文件名,避免同名覆盖丢失数据
- BMP 负高度取绝对值,自顶向下格式解析正确
- 新增 {目录名}-picker 白名单输出目录,整理后跳过重复扫描
- 分类目录名去掉 uuid 前缀,重复运行并入已有目录
2025-03-15 21:17:24 +08:00

90 lines
6.0 KiB
Markdown
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.
# 项目审查记录 2026-08-13
> 审查方式:静态代码审查(`go build` / `go vet` 均通过,此文件不含编译级错误)
> 审查范围:全部 `.go` 源码
---
## 一、严重 Bug
### 1. WEBP / BMP / PSB 永远进「读取异常」文件夹(专用分支是死代码)
- **位置**:`util/image.go:9-19`、`core/handle_image.go:22,35,46`
- **问题**:`supportImageTypes` 中包含了 `.bmp`、`.webp`、`.psb`,导致 `handle_image.go:22` 的通用分支总是先命中,调用 `image.DecodeConfig`(`main.go:6-8` 只注册了 png/jpeg/gif 解码器),对 webp/bmp 必然失败,文件全部落入「读取异常」目录。
- **影响**:`handle_image.go:35`(webp)、`:46`(bmp)的专用处理分支永远不会执行,与 README 承诺支持的格式不符。
- **修复方向**:从 `supportImageTypes` 中移除 `.bmp` / `.webp` / `.psb`,让专用分支生效;或在通用分支前先特判这三类格式。
### 2. PSD 从未被识别为图片,`ImagePsdList` 恒为空
- **位置**:`core/file_scanner.go:70-79`、`core/handle_image.go:57`
- **问题**:PSD 文件的 MIME 为 `application/vnd.adobe.photoshop`(不包含 `image/` 前缀),且 `.psd` 不在 `supportImageTypes` 中,因此在 `DoFilter` 阶段就被丢弃,永远不会进入 `GlobalImagePathList`。
- **影响**:`handle_image.go:57` 的 PSD 分支不可达,README 声称的「PSD 单独归入图片_PSD」功能实际失效。
- **修复方向**:在过滤阶段对 `.psd` / `application/vnd.adobe.photoshop` 单独识别并入图片列表。
### 3. 同名文件移动时数据丢失风险(已处理)
- **位置**:`util/video.go:152-169`(`moveFileToDir`)
- **问题**:目标文件名只取 `BaseName`。不同子目录下的同名文件(如 `a/photo.jpg`、`b/photo.jpg`)会被移动到/复制到同一目标:Unix 下 `os.Rename` 静默覆盖,跨盘 fallback 的 `copyFile`(`os.Create`)也会截断覆盖目标。
- **影响**:真实数据丢失风险,且无任何告警。
- **修复方向**:目标名冲突时追加序号或 hash,确保不覆盖已有文件。
### 4. BMP 自顶向下格式(负高度)导致解析错乱(已处理)
- **位置**:`core/bmp.go:59`、`core/handle_image.go:96-98`
- **问题**:`ReadBmpImage` 直接返回 `int32` 宽高,负高度被 `fmt.Sprintf("%d-%d")` 拼成 `"640--480"`,`strings.Split("-")` 后 `width2Height[1]` 为空串,`String2int` 返回 0,图片被错误归类。
- **影响**:此类 BMP 图片分辨率判定错误(高度变 0,全部按横屏普通处理)。
- **修复方向**:读取时对高度取绝对值,或改用不易混淆的分隔符/结构化存储。
### 5. 重复运行会重新整理已整理过的目录(已处理)
- **位置**:`core/file_scanner.go:20`、`main.go`
- **问题**:`filepath.Walk` 扫描整个根目录。第二次运行时,上次生成的 `{uid}-图片_*`、`{uid}-视频_*` 等目录会被再次扫描,其中已分类的文件会被再次移动,形成无限嵌套/重复归类。
- **影响**:重复执行程序导致目录结构越来越乱,违背 README「重复运行不会相互覆盖」的描述。
- **修复方向**:扫描时跳过已生成的 `{uid}-` 前缀目录,或提供过滤白名单。
---
## 二、次要问题
### 6. ffprobe 输出解析脆弱
- **位置**:`util/video.go:53-101`
- **问题**:对多视频流(常见于 MKV)的多行输出处理靠猜测(`\r\n\r\n\r\n\r\n` split、`N/AxN/A` 字符串替换等),且不校验 0 值分辨率,解析出错时归类到「普通」而非「读取异常」。
### 7. 视频「读取异常 / 已忽略」目录命名不一致
- **位置**:`core/handle_video.go:56,62`
- **问题**:这两个目录没有 uid 前缀(如 `读取异常`、`已忽略`),与其它 `{uid}-视频_*` 目录风格不统一,且与图片侧带 uid 的命名方式不一致。
### 8. 死代码 / 未使用数据
- **位置**:`util/file.go:47-112`、`vars/video.go`、`util/file.go:17-21`、`vars/global.go:5`
- **问题**:`VideoPath2DurationMap` / `VideoPath2WidthHeightTagMap` 赋值后从未使用(重命名逻辑已被注释掉);`util/file.go` 中保留大段注释代码;`GetFileDirectory`、`GlobalFilePath2FileNameMap` 未被使用。
### 9. `doPickImageFile` 空判断误报
- **位置**:`core/handle_image.go:91`
- **问题**:判断的是全局 `vars.ImagePath2WidthHeightMap` 而非入参 `imagePath2WidthHeightMap`;当所有图片都是错误/忽略时,会误打印「当前目录下没有扫描到图片文件」。
### 10. 目录创建失败未处理
- **位置**:`core/handle_image.go`(各 `move*Image` 函数)、`core/handle_video.go`(各 `move*Video` 函数)
- **问题**:多数 `util.CreateDir` 的返回值被忽略,若目录创建失败仍继续执行 `DoMoveFileToDir`,文件移动会静默失败。
### 11. 临时 ffprobe.exe 清理不保证
- **位置**:`core/handle_video.go:13-24,68-71`
- **问题**:通过流程末尾手动 `os.Remove` 清理,若中途异常(panic / 提前 return)会残留 `ffprobe.exe`;下次运行该文件会被扫描当作普通文件。建议 `defer` 清理。
---
## 三、优化建议
1. **修复严重 bug 1/2 的关键**:调整 `supportImageTypes` 列表 / 过滤逻辑,确保 webp、bmp、psb、psd 走各自正确的分支。
2. **重复运行防护**:扫描时跳过已生成的 `{uid}-` 目录。
3. **合并 ffprobe 调用**:分辨率 + 时长可用一次 `-show_streams -show_format` 取回,每视频省一次子进程创建。
4. **消除重复代码**:图片/视频各有约 60 个几乎相同的分组 + 移动函数,可用「分组名 → 列表」映射表驱动,大幅减小编码量。
5. **使用 `filepath.Join`**:代替 `rootDir + separator + ...` 字符串拼接,避免路径分隔符与平台问题。
6. **`moveFileToDir` 增加同名去重**:冲突时追加序号/hash,杜绝覆盖。
7. **清理死代码**:删除注释掉的 rename 逻辑、未使用的 map 与函数。