import time import logging import os from frame_finder import FrameFinder from frame import FrameFormat from typing import Tuple, Dict class FrameProcessor: """帧处理器 - 处理帧数据并统计信息""" # 缓冲区大小设置为64KB,可以根据实际情况调整 BUFFER_SIZE = 64 * 1024 # 64KB def __init__(self): """初始化帧处理器""" self.finder = FrameFinder() self.frame_count = 0 self.valid_frames = 0 self.corrupt_frames = 0 self.invalid_bytes = 0 self.start_time = None self.total_bytes_processed = 0 self.buffer = bytearray() # 用于存储未处理完的数据 def process_buffer(self, data: bytes) -> Tuple[int, int, int, int]: """ 处理数据缓冲区 Args: data: 要处理的数据 Returns: Tuple[int, int, int, int]: (总帧数, 有效帧数, 损坏帧数, 无效字节数) """ if self.start_time is None: self.start_time = time.time() self.total_bytes_processed += len(data) # 将新数据添加到缓冲区 self.buffer.extend(data) # 如果缓冲区过大,可以在这里添加清理逻辑 # if len(self.buffer) > self.BUFFER_SIZE * 2: # self.buffer = self.buffer[-self.BUFFER_SIZE:] while len(self.buffer) > 0: frame_data, next_pos = self.finder.find_frame_in_buffer(self.buffer) if frame_data: self.frame_count += 1 if FrameFormat.parse_frame(frame_data): self.valid_frames += 1 else: self.corrupt_frames += 1 # 更新缓冲区 self.buffer = self.buffer[next_pos:] else: # 如果没有找到帧,next_pos 表示需要保留的数据起始位置 if next_pos == len(self.buffer): break elif next_pos == 0: break else: # 移除无效数据 self.invalid_bytes += next_pos self.buffer = self.buffer[next_pos:] return self.frame_count, self.valid_frames, self.corrupt_frames, self.invalid_bytes def process_file(self, file_path: str) -> Tuple[int, int, int, int]: """ 处理文件 Args: file_path: 文件路径 Returns: Tuple[int, int, int, int]: (总帧数, 有效帧数, 损坏帧数, 无效字节数) """ if not os.path.exists(file_path): raise FileNotFoundError(f"找不到文件: {file_path}") with open(file_path, 'rb') as f: while True: # 使用64KB的缓冲区读取数据 data = f.read(self.BUFFER_SIZE) if not data: break self.process_buffer(data) return self.frame_count, self.valid_frames, self.corrupt_frames, self.invalid_bytes def get_statistics(self) -> Dict: """ 获取处理统计信息 Returns: Dict: 统计信息 """ if self.start_time is None: runtime = 0 else: runtime = time.time() - self.start_time stats = { "total_bytes_processed": self.total_bytes_processed, "total_frames": self.frame_count, "valid_frames": self.valid_frames, "corrupt_frames": self.corrupt_frames, "invalid_bytes": self.invalid_bytes, "runtime": runtime, "bytes_per_second": self.total_bytes_processed/runtime if runtime > 0 else 0, "frames_per_second": self.frame_count/runtime if runtime > 0 else 0 } return stats def print_statistics(stats: Dict, file_name: str = None) -> None: """ 打印统计信息 Args: stats: 统计信息 file_name: 文件名(可选) """ print("\n\n=================== 测试统计 ===================") if file_name: print(f"测试文件: {file_name}") print(f"数据大小: {stats['total_bytes_processed']:,} 字节") print(f"运行时间: {stats['runtime']:.3f} 秒") print("\n处理性能:") print(f"- 平均处理速度: {stats['bytes_per_second']:,.1f} 字节/秒") print(f"- 帧处理速度: {stats['frames_per_second']:,.1f} 帧/秒") print("\n帧统计:") print(f"- 总帧数: {stats['total_frames']}") print(f"- 有效帧数: {stats['valid_frames']}") print(f"- 损坏帧数: {stats['corrupt_frames']}") print(f"- 无效字节数: {stats['invalid_bytes']:,}") print("===============================================") def main(): # 配置日志 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) # 从文件加载测试数据 test_data_dir = "./test_data" test_file = "test_frames.bin" test_file_path = os.path.join(test_data_dir, test_file) print(f"尝试读取测试文件: {test_file_path}") if not os.path.exists(test_file_path): print(f"错误:找不到测试文件: {test_file_path}") print("请先运行 generate_test_data.py 生成测试数据") return try: # 创建处理器 processor = FrameProcessor() # 处理文件 processor.process_file(test_file_path) # 打印统计信息 print_statistics(processor.get_statistics(), os.path.basename(test_file_path)) except Exception as e: print(f"错误:处理失败 - {e}") return if __name__ == "__main__": main()