Python代理服务器如何将所有流经字节数据完整写入同一个文件
核心问题出在文件打开模式和打开时机错误:
- 若你将
with open('data.txt', 'wb') as f: f.write(data)这段代码放在数据接收循环内部,wb二进制写入模式每次打开文件时会默认清空已有内容,再写入当前单块缓冲区的数据,最终自然只能保留单次写入的结果。 - 就算临时改成
ab二进制追加模式反复打开文件,虽然能解决内容覆盖问题,但会带来不必要的IO开销,代理高并发场景下还可能出现文件占用冲突。
推荐解决方案
方案1:全程保持文件打开(性能最优,适合单进程单输出文件场景)
在代理启动阶段、数据接收循环外就打开文件,所有需要存储的数据直接写入已打开的文件对象,代理进程退出前再统一关闭文件即可。
修改后的代码参考:
# 循环外提前打开文件,全程复用同一个文件对象 with open('data.txt', 'wb') as f: try: for sock in reader: data = sock.recv(BUFSIZE) if not data: return if sock is socket_dst: socket_src.send(data) else: socket_dst.send(data) print(data) # 直接写入已打开的文件,不会覆盖原有内容 f.write(data) # 如果需要实时落盘不做缓存,可加下方flush语句 # f.flush() except socket.error as err: error("Loop failed", err) return
如果你的代理需要处理多连接,且不同连接的流量要写入不同文件,给每个连接单独维护一个文件对象,连接断开时关闭对应文件即可。
方案2:追加模式打开(适合临时调试,不想改动代码结构场景)
如果不想调整现有代码结构,只需把原来的打开模式从wb改为ab(二进制追加模式),每次写入时不会清空原有内容,会自动在文件末尾追加新的字节:
# ab为二进制追加模式,写入时保留原有内容 with open('data.txt', 'ab') as f: f.write(data)
注意该方案不要在高并发场景使用,频繁打开关闭文件的IO开销很高。
额外提示
如果需要区分图片、文本等不同类型的资源分开存储,你需要先解析HTTP流量的请求/响应头,拿到Content-Type和Content-Length字段,判断资源类型后写入对应后缀的文件,否则所有流量混写在同一个txt文件里无法直接识别出可用的图片资源。
二进制写入本身已经是保留原始字节的最优方式,不会修改任何流经的原始数据,不需要额外做编码转换。
内容的提问来源于stack exchange,提问作者Anonymous27
相关产品推荐
相关产品推荐

