再次优化目录扫描逻辑,哈希值比对文件

再次优化目录扫描逻辑,哈希值比对文件
This commit is contained in:
fantasticbin 2025-03-04 14:52:18 +08:00
parent 91d751df7d
commit 6e264ae8af

View File

@ -6,6 +6,7 @@ import (
"fmt"
"github.com/spf13/viper"
"golang.org/x/sync/errgroup"
"hash/crc32"
"image"
_ "image/jpeg"
"io"
@ -52,13 +53,21 @@ func (c *Crawler) isVideoFile(fileName string) bool {
return false
}
// 获取文件信息,包括大小和修改时间
func (c *Crawler) getFileInfo(filePath string) (int64, string, error) {
info, err := os.Stat(filePath)
// 获取文件 CRC32 哈希值
func (c *Crawler) getFileInfo(filePath string) (uint32, error) {
file, err := os.Open(filePath)
if err != nil {
return 0, "", err
return 0, err
}
return info.Size(), info.ModTime().String(), nil
defer file.Close()
// 使用快速 CRC32 校验,仅读取前 4KB 内容
buf := make([]byte, 4096)
n, err := file.Read(buf)
if err != nil && err != io.EOF {
return 0, err
}
return crc32.ChecksumIEEE(buf[:n]), nil
}
// 获取代码数字
@ -184,6 +193,11 @@ func (c *Crawler) Handle() error {
return fmt.Errorf("访问路径 %s 失败: %w", path, err)
}
// 目录过滤
if info.IsDir() {
return nil
}
// 仅处理视频文件
if !c.isVideoFile(info.Name()) {
return nil
@ -191,14 +205,14 @@ func (c *Crawler) Handle() error {
baseName := strings.TrimSuffix(info.Name(), filepath.Ext(info.Name()))
// 获取文件大小和修改时间
fileSize, modTime, err := c.getFileInfo(path)
// 获取文件哈希
fileHash, err := c.getFileInfo(path)
if err != nil {
return fmt.Errorf("获取文件信息失败 %s: %w", baseName, err)
return fmt.Errorf("获取文件哈希失败 %s: %w", baseName, err)
}
// 根据文件的大小和修改时间生成唯一的文件标识
uniqueID := fmt.Sprintf("%d-%s", fileSize, modTime)
// 使用文件名+哈希值作为唯一标识
uniqueID := fmt.Sprintf("%s-%d", baseName, fileHash)
if _, exists := uniqueFiles[uniqueID]; !exists {
uniqueFiles[uniqueID] = struct{}{}
videoFiles = append(videoFiles, baseName)