如何将Python Socket接收的原始十六进制数据快速写入文件
高效处理Socket接收的Bytes数据并写入十六进制格式文件
我通过Python Socket接收以太网传来的原始十六进制数据,Socket的recv()方法返回bytes类型。假设接收的数据是10字节的b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09',需要以最快速度(适配700 Mbit/s的流数据吞吐量)将其按每行两位十六进制的形式写入文件,要求不进行解码,最终文件每行对应一个字节的十六进制值(比如00、01这类格式)。
测试发现直接打印bytes数据会显示转义形式,用decode()方法会把可解码字符转为对应字符(比如b'\x41'解码成A),不可解码的则显示空白。测试代码如下:
data = [] for i in range(10): data.append(i) data = bytes(data) print(data) print(data.decode()) a = b'\x41' print(a) print(a.decode())
解决方案
要适配700 Mbit/s的高吞吐量,必须采用底层优化的批量操作,避免逐字节循环带来的性能损耗:
- 批量转换十六进制:使用
binascii.hexlify()将整个bytes对象一次性转换为十六进制字节串(如b'\x00\x01'转为b'0001'),该函数是C实现的,性能远优于Python层面的循环处理。 - 批量分割与写入:将转换后的十六进制字节串按每两个字符分割,批量添加换行符后写入文件,减少I/O操作次数。
示例代码
import binascii import socket # 初始化Socket连接(根据实际场景调整) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(("目标IP地址", 目标端口)) # 以二进制模式打开文件,避免编码转换开销 with open("hex_output.txt", "wb") as f: while True: # 每次接收大缓冲区数据,减少系统调用次数(可根据实际调整缓冲区大小) chunk = sock.recv(8192) if not chunk: break # 连接断开时退出循环 # 批量转换为十六进制字节串 hex_chunk = binascii.hexlify(chunk) # 分割为每行两个字符,添加换行符后批量写入 lines = b'\n'.join(hex_chunk[i:i+2] for i in range(0, len(hex_chunk), 2)) + b'\n' f.write(lines)
关键优化点
- 二进制写入:用
wb模式打开文件,跳过文本模式的编码/解码步骤,降低开销。 - 大缓冲区接收:每次接收8192字节(或更大),减少Socket调用次数,提升吞吐量。
- 批量操作:所有转换、分割步骤均为批量处理,避免逐字节操作的性能瓶颈。
如果需要进一步压榨性能,可以考虑使用io.BufferedWriter增大写入缓冲区,或者将多个接收块合并后再处理,进一步减少I/O次数。
内容的提问来源于stack exchange,提问作者efe373
相关产品推荐
相关产品推荐

