Установите Драгоценный камень Фасетов Ruby и используйте их Массив to_h .
Вы используете интерфейс слишком высокого уровня, чтобы иметь хороший контроль над такими проблемами, как блокировка и буферизация размеров блоков. Если вы не готовы полностью перейти на асинхронный интерфейс (в этом случае twisted , уже предложенный, трудно превзойти!), Почему бы не httplib , который после все в стандартной библиотеке? Метод HTTPResponse instance .read (amount)
с большей вероятностью будет блокироваться не дольше, чем необходимо для чтения amount
байтов, чем аналогичный метод для объекта, возвращенного urlopen
(хотя, по общему признанию, нет никаких задокументированных спецификаций по этому поводу ни для одного модуля, хммм ...).
Эй, это три вопроса в одном! ; -)
Иногда он мог блокироваться - даже если ваш сервер генерирует данные довольно быстро, узкие места в сети теоретически могут привести к блокировке чтения.
Чтение данных URL с использованием «for dat in req» будет означать чтение построчно - не очень полезно, если вы читаете двоичные данные, такие как изображение. Вы получите лучший контроль, если используете
chunk = req.read(size)
, который, конечно, может блокировать.
Будет ли это лучшим способом, зависит от специфики, недоступной в вашем вопросе. Например, если вам нужно работать без каких-либо блокирующих вызовов, вам нужно рассмотреть такую структуру, как Twisted . Если вы не хотите, чтобы блокировка мешала вам, и не хотите использовать Twisted (что является совершенно новой парадигмой по сравнению с блокирующим способом действий),
Да, когда вы догоните сервер, он будет блокироваться до тех пор, пока сервер не произведет больше данных
Каждое данные будут одной строкой, включая новую строку на конце
скрученный - хороший вариант
Я бы поменял местами с и вокруг в вашем примере, вы действительно хотите открывать и закрывать файл для каждой поступающей строки?
Другой вариант - напрямую использовать модуль сокета
. Установите соединение, отправьте HTTP-запрос, установите сокет в неблокирующий режим, а затем прочтите данные с помощью socket.recv ()
обработки исключений «Ресурс временно недоступен» (что означает, что нечего читать). Вот очень грубый пример:
import socket, time
BUFSIZE = 1024
s = socket.socket()
s.connect(('localhost', 1234))
s.send('GET /path HTTP/1.0\n\n')
s.setblocking(False)
running = True
while running:
try:
print "Attempting to read from socket..."
while True:
data = s.recv(BUFSIZE)
if len(data) == 0: # remote end closed
print "Remote end closed"
running = False
break
print "Received %d bytes: %r" % (len(data), data)
except socket.error, e:
if e[0] != 11: # Resource temporarily unavailable
print e
raise
# perform other program tasks
print "Sleeping..."
time.sleep(1)
Однако urllib.urlopen ()
имеет некоторые преимущества, если веб-сервер выполняет перенаправление, вам нужна базовая аутентификация на основе URL и т.д. Вы можете использовать select
модуль, который сообщит вам, когда есть данные для чтения.