4. 车载视频循环覆盖存储策略
任务目标
实现一个车载视频循环覆盖存储管理器:当新片段写入导致总占用超过容量上限时,按录制时间从旧到新删除已有片段,直到腾出足够空间,保证录像持续写入不中断。
核心设计
- 每个片段记录:文件名、大小(字节)、录制起始时间戳。
- 写入前先检查剩余空间;不足则循环删除最旧片段,直到空间足够。
- 若单个新片段大于总容量,直接拒绝写入并返回失败,避免死循环。
- 删除顺序严格按时间戳升序(最旧优先),与文件名无关。
完整实现(Python)
import os
import time
from dataclasses import dataclass, field
@dataclass
class Clip:
name: str
size: int # 字节
start_ts: float # 录制起始时间戳
class CircularStorage:
def __init__(self, capacity: int):
self.capacity = capacity
self.clips: list[Clip] = []
@property
def used(self) -> int:
return sum(c.size for c in self.clips)
def _oldest(self) -> Clip:
return min(self.clips, key=lambda c: c.start_ts)
def write(self, name: str, size: int, start_ts: float | None = None) -> bool:
if size > self.capacity:
print(f"[拒绝] {name} 大小 {size} 超过总容量 {self.capacity}")
return False
start_ts = time.time() if start_ts is None else start_ts
while self.used + size > self.capacity:
victim = self._oldest()
self.clips.remove(victim)
print(f"[覆盖] 删除最旧片段 {victim.name} ({victim.size} 字节)")
self.clips.append(Clip(name, size, start_ts))
print(f"[写入] {name} 成功,当前占用 {self.used}/{self.capacity}")
return True
def status(self) -> str:
order = sorted(self.clips, key=lambda c: c.start_ts)
return " | ".join(f"{c.name}({c.size})" for c in order) or "(空)"
if __name__ == "__main__":
store = CircularStorage(capacity=1000)
store.write("clip_01.mp4", 400, start_ts=1)
store.write("clip_02.mp4", 400, start_ts=2)
store.write("clip_03.mp4", 400, start_ts=3) # 触发覆盖,删除 clip_01
store.write("clip_04.mp4", 900, start_ts=4) # 触发覆盖,删除 clip_02、clip_03
store.write("clip_05.mp4", 1200, start_ts=5) # 超过总容量,拒绝
print("最终片段顺序:", store.status())
运行与验证
python circular_storage.py
观察输出并核对以下判定条件:
- 写入 clip_03 时,因 400+400+400 > 1000,应删除最旧的 clip_01,剩余 clip_02、clip_03。
- 写入 clip_04(900 字节)时,需连续删除 clip_02、clip_03 才能腾出空间,最终只剩 clip_04。
- 写入 clip_05(1200 字节)时,因单片段超过总容量 1000,应返回 False 并打印拒绝信息,不删除任何已有片段。
- 最终
status()输出应为clip_04.mp4(900),且写入过程从未因空间不足而中断。
落地要点
- 真实车载场景中,
size与start_ts由录像模块在片段封口时提供,删除动作需同步调用文件系统os.remove,本示例聚焦策略逻辑,未接入真实文件 IO。 - 若需持久化,可在每次写入/删除后把
clips序列化到索引文件,重启时恢复,避免重新扫描目录。 - 容量上限建议预留少量余量(如 95%),防止文件系统元数据或索引占用导致写入失败。