来自http流的非阻塞读取/记录

Cor*_*erg 6 python logging http urllib2

我有一个客户端连接到HTTP流并记录它消耗的文本数据.

我向流服务器发送HTTP GET请求...服务器回复并不断发布数据......它将发布文本或定期发送ping(文本)消息...并且永远不会关闭连接.

我需要以非阻塞方式读取和记录它消耗的数据.

我正在做这样的事情:

import urllib2

req = urllib2.urlopen(url)    
for dat in req: 
    with open('out.txt', 'a') as f:        
        f.write(dat) 
Run Code Online (Sandbox Code Playgroud)

我的问题是:
当流连续时,这会阻塞吗?
每个块中读取了多少数据,是否可以指定/调整?
这是读取/记录http流的最佳方式吗?

Vin*_*jip 6

嘿,这是一个三个问题!;-)

它有时可能会阻塞 - 即使您的服务器很快生成数据,网络瓶颈理论上也可能导致您的读取被阻塞.

使用"for data in req"读取URL数据意味着一次读取一行 - 如果您正在读取图像等二进制数据,则不是很有用.如果使用,您可以获得更好的控制

chunk = req.read(size)
Run Code Online (Sandbox Code Playgroud)

这当然可以阻止.

这是否是最好的方式取决于您的问题中没有的具体细节.例如,如果你需要在没有阻塞调用的情况下运行,你需要考虑像Twisted这样的框架.如果你不想让阻塞阻止你并且不想使用Twisted(这是一种全新的范式与阻塞的做事方式相比),那么你可以启动一个线程来进行读取和写入文件,而你的主要线程以其快乐的方式:

def func(req):
    #code the read from URL stream and write to file here

...

t = threading.Thread(target=func)
t.start() # will execute func in a separate thread
...
t.join() # will wait for spawned thread to die
Run Code Online (Sandbox Code Playgroud)

显然,我已经省略了错误检查/异常处理等,但希望它足以为您提供图片.


Ale*_*lli 3

您使用的接口太高级,无法很好地控制阻塞和缓冲块大小等问题。如果您不愿意一直使用异步接口(在这种情况下,已经建议的twisted很难被击败!),为什么不使用httplib呢,毕竟它在标准库中?与返回的对象上的类似方法相比,HTTPResponse 实例.read(amount)方法更有可能阻塞不超过读取字节所需的时间(尽管无可否认,这两个模块上都没有关于该方法的文档化规范,嗯......)。amounturlopen