人脸识别考勤系统重复写入CSV文件的问题,本质是写入逻辑没有做好去重和并发控制,导致同一条考勤记录被多次写入存储文件。这类问题会让后续的考勤统计、薪资核算等工作出现偏差,需要针对性优化写入流程。

问题常见原因分析
出现重复写入的情况,通常有以下几类原因:
- 人脸识别算法识别到同一人员后,短时间内多次触发写入回调,没有做识别间隔限制
- 考勤记录没有唯一标识,写入前没有校验该记录是否已经存在于CSV文件中
- 多进程或多线程同时操作同一个CSV文件,没有做并发锁控制,导致重复写入
- 考勤人员长时间停留在识别区域,系统反复判定为有效考勤并触发写入
具体解决方案
1. 设置识别触发间隔阈值
可以通过记录上一次有效识别的时间,限制同一人员两次写入的最小间隔,避免短时间重复触发。以下是Python实现的示例:
import time
# 存储人员上次识别时间的字典,key为人员ID,value为上次识别时间戳
last_recognize_time = {}
# 最小识别间隔,单位秒,可根据实际需求调整
MIN_INTERVAL = 60
def check_recognize_interval(user_id):
current_time = time.time()
# 如果该人员之前没有识别记录,直接允许写入
if user_id not in last_recognize_time:
last_recognize_time[user_id] = current_time
return True
# 计算距离上次识别的时间差
time_diff = current_time - last_recognize_time[user_id]
if time_diff >= MIN_INTERVAL:
last_recognize_time[user_id] = current_time
return True
return False
2. 写入前校验记录唯一性
给每条考勤记录添加唯一标识,比如人员ID+考勤日期+考勤时段的组合,写入前先读取CSV文件校验该标识是否已存在,避免重复写入。示例如下:
import csv
from datetime import datetime
def is_record_exists(user_id, record_date, time_slot):
# 唯一标识组合:人员ID+日期+时段
target_key = f"{user_id}_{record_date}_{time_slot}"
try:
with open("attendance.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
# 跳过表头
next(reader, None)
for row in reader:
# 假设CSV列顺序为:人员ID,日期,时段,打卡时间
exist_key = f"{row[0]}_{row[1]}_{row[2]}"
if exist_key == target_key:
return True
except FileNotFoundError:
# 文件不存在说明没有历史记录,直接返回不存在
return False
return False
def write_attendance_record(user_id, record_date, time_slot, check_time):
# 先校验记录是否已存在
if is_record_exists(user_id, record_date, time_slot):
print("该考勤记录已存在,跳过写入")
return
# 写入新记录
with open("attendance.csv", "a", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
writer.writerow([user_id, record_date, time_slot, check_time])
3. 添加文件写入锁机制
如果是多进程或多线程场景操作同一个CSV文件,需要使用文件锁避免并发写入冲突。以下是使用fcntl模块实现的文件锁示例,适用于Linux/macOS系统:
import fcntl
import csv
from datetime import datetime
def safe_write_record(user_id, record_date, time_slot, check_time):
# 先调用之前的唯一性校验逻辑
if is_record_exists(user_id, record_date, time_slot):
return
# 打开文件并加锁
with open("attendance.csv", "a", encoding="utf-8", newline="") as f:
# 获取排他锁,阻塞直到获取到锁
fcntl.flock(f, fcntl.LOCK_EX)
try:
# 加锁后再次校验,避免加锁前其他进程已经写入
if not is_record_exists(user_id, record_date, time_slot):
writer = csv.writer(f)
writer.writerow([user_id, record_date, time_slot, check_time])
finally:
# 释放锁
fcntl.flock(f, fcntl.LOCK_UN)
方案组合建议
实际落地时建议将三种方案结合使用:首先设置识别间隔阈值过滤短时间重复触发,其次在写入前做唯一标识校验,最后如果是多进程场景添加文件锁,三重保障可以彻底解决重复写入CSV文件的问题。如果系统使用的是其他编程语言,也可以参考上述逻辑,调整对应语言的文件操作和锁机制实现即可。
人脸识别考勤CSV文件写入重复数据去重文件锁机制Python数据处理修改时间:2026-06-28 15:51:27