asyncio aiohttp - ошибка чтения клиентом закрытого файла - PullRequest
0 голосов
/ 11 декабря 2018

Это код:

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 (), это сработает,Но я не хочу открывать файл несколько раз.

1 Ответ

0 голосов
/ 11 декабря 2018

Проблема в том, что open(...) возвращает файловый объект , и вы передаете один и тот же файловый объект всем start() сопрограммам, которые вы создаете на верхнем уровне.Экземпляр сопрограммы, который запланирован первым, передаст объект файла в session.post() как часть параметра data, а session.post() прочитает файл до конца и закроет объект файла.Следующая сопрограмма start() попытается выполнить чтение из теперь закрытого объекта, что вызовет исключение.

Чтобы устранить проблему, не открывая файл несколько раз, необходимо убедиться, что на самом деле прочитано данные в виде байтового объекта:

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

Это передаст один и тот же байтовый объект всем сопрограммам, которые должны работать должным образом.

...