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()}
这会将相同的字节对象传递给所有协程,这应该会按预期工作。
这是代码:
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()}
这会将相同的字节对象传递给所有协程,这应该会按预期工作。