172 lines
5.8 KiB
Python
172 lines
5.8 KiB
Python
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() |