在AsyncIO函数中使用多await遇文件写入问题,求解决方案
问题分析与解决方法
核心问题
你遇到的file_writer.write()执行失败,本质是数据类型不匹配:
msg是receive_json()返回的Python字典对象,而以wb(二进制写入)模式打开的文件,只能接收字节类型数据,无法直接写入字典。
修正方案
步骤1:序列化并编码数据
把字典转为JSON字符串,再编码成UTF-8字节,才能写入二进制文件。
步骤2:优化代码逻辑
- 调整初始化顺序,确保文件和队列先于任务创建完成,避免属性未初始化的问题
- 添加文件刷新和关闭逻辑,防止资源泄漏
- 可选捕获额外异常,便于排查问题
修正后的完整代码
import json import asyncio import aiofiles # 假设你的类定义框架如下 # class YourWebSocketClient: # def __init__(self, client): # self.client = client async def setup(self): self.ws = await self.client.ws_connect() # Aiohttp client session self.rx_queue = asyncio.Queue() # 先初始化文件写入器和队列,再创建任务 self.file_writer = await aiofiles.open('server_log.txt', 'wb') self.rx_task = asyncio.create_task(self._rx_task()) # 更简洁的任务创建方式 async def _rx_task(self): """Async function to collect messages, write to file and put into queue.""" try: while True: msg = await self.ws.receive_json() # 将字典序列化为JSON字符串,编码为UTF-8字节 msg_bytes = json.dumps(msg, ensure_ascii=False).encode('utf-8') # 写入文件,添加换行符分隔每条日志 await self.file_writer.write(msg_bytes + b'\n') # 强制刷新缓冲区,确保数据立即写入磁盘 await self.file_writer.flush() # 放入队列 self.rx_queue.put_nowait(msg) except asyncio.CancelledError: # 任务取消时关闭文件,释放资源 await self.file_writer.close() except Exception as e: # 捕获其他异常(如JSON序列化失败、写入错误) print(f"rx_task error: {str(e)}")
额外说明
json.dumps(msg, ensure_ascii=False):保留中文等非ASCII字符,避免转义成Unicode编码await self.file_writer.flush():默认情况下aiofiles会缓存写入内容,调用flush可以确保数据立即写入磁盘- 任务取消时关闭文件:防止程序退出时文件未正常关闭导致数据丢失
内容的提问来源于stack exchange,提问作者Albert Gregor
相关产品推荐
相关产品推荐

