diff --git a/crawler.go b/crawler.go index 059af86..9979f4e 100644 --- a/crawler.go +++ b/crawler.go @@ -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)