asyncio aiohttp - 客户端读取关闭的文件错误

asyncio aiohttp - client read of closed file error

这是代码:

import asyncio
import aiohttp
loop = asyncio.get_event_loop()
session = aiohttp.ClientSession(loop=loop)
data = {'file': open('test_img.jpg', 'rb')}

async def start():
        async with session.post("http://localhost", data=data) as response:
            text = await response.text()
            print(text)

loop.run_until_complete(asyncio.gather(*[start() for i in range(20)]))

我收到一个错误:

ValueError: read of closed file

但是,如果我将 open() 调用移动到 start() 函数内部,它就会起作用。但是我不想多次打开文件。

问题是 open(...) returns 一个 file object,并且您将同一个文件对象传递给您在顶层创建的所有 start() 协程.恰好先被调度的协程实例会将文件对象作为data参数的一部分传递给session.post(),而session.post()会读取文件到最后并关闭文件对象。下一个 start() 协程将尝试从现在关闭的对象中读取,这将引发异常。

要在不多次打开文件的情况下解决问题,您需要确保实际读取字节对象的数据:

data = {'file': open('test_img.jpg', 'rb').read()}

这会将相同的字节对象传递给所有协程,这应该会按预期工作。