在Python中用超时读取文件

在Linux中,有一个文件/sys/kernel/debug/tracing/trace_pipe ,正如名称/sys/kernel/debug/tracing/trace_pipe ,它是一个pipe道。 所以,假设我想使用Python读取前50个字节,然后运行以下代码:

 $sudo python -c 'f=open("/sys/kernel/debug/tracing/trace_pipe","r"); print f; print f.read(50); f.close()<br> <open file '/sys/kernel/debug/tracing/trace_pipe', mode 'r' at 0xb7757e90> 

我们可以看到打开文件的速度很快(如果我们拥有超级用户的权限) – 但是,如果trace_pipe文件在这个时候是空的,它将会被阻塞(即使有内容,内容也会被丢弃,直到没有更多,然后再次文件将阻止)。 然后,我不得不按CtrlC中断Python脚本与KeyboardInterrupt

我如何让Python 2.7做一个超时读取?

也就是说,我想指示Python “尝试从这个文件中读取50个字节;如果你一秒钟之后没有成功,放弃并返回”

Solutions Collecting From Web of "在Python中用超时读取文件"

使用

 os.read(f.fileno(), 50) 

代替。 这不会等到指定的字节数已被读取,而是在读取任何内容(至多指定的字节数)时返回。

这并不能解决你的问题,因为你无法从管道中读取任何东西 。 在这种情况下,您应该使用select从模块select测试是否有东西要读取。

编辑:

使用select测试空输入:

 import select r, w, e = select.select([ f ], [], [], 0) if f in r: print os.read(f.fileno(), 50) else: print "nothing available!" # or just ignore that case 
 f = os.open("/sys/kernel/debug/tracing/trace_pipe", os.O_RDONLY|os.O_NONBLOCK) 

应该防止阻塞(在Unix中工作)..没有必要在这里选择..

只要添加这个注意,为了更好的格式化:

@在我的情况下,阿尔菲的答案是:

 $ sudo python -c 'import os, select; f=open("/sys/kernel/debug/tracing/trace_pipe","r"); print f; rrdy, wrdy, xrdy = select.select([f], [], [], 1); print rrdy, wrdy, xrdy ; timeout= "timed out" if (rrdy==[]) else "" ; print timeout; print os.read(f.fileno(), 50) if timeout=="" else ""; f.close() ' 

如果文件中有东西,我会得到如下回应:

 <open file '/sys/kernel/debug/tracing/trace_pipe', mode 'r' at 0xb76f0e90> [<open file '/sys/kernel/debug/tracing/trace_pipe', mode 'r' at 0xb76f0e90>] [] [] Xorg-1033 [001] 12570.075859: <user s 

如果文件中没有任何内容,我会得到:

 <open file '/sys/kernel/debug/tracing/trace_pipe', mode 'r' at 0xb7831e90> [] [] [] timed out 

请注意, select文档不是显式的, timeout参数是以秒为单位 – 但浮点值(例如0.5)也可以工作。

@ GabiMe的回答:

 $ sudo python -c 'import os; filno = os.open("/sys/kernel/debug/tracing/trace_pipe", os.O_RDONLY|os.O_NONBLOCK); f=os.fdopen(filno, "r"); print f; print "A", f.read(50); print "B", os.read(f.fileno(), 50); f.close() ' 

如果文件中有东西,我会得到如下回应:

 <open file '<fdopen>', mode 'r' at 0xb77b6e90> A bash-13777 [000] 13694.404519: sys_exi B Timer-31065 [001] 13694.404830: sys_exi 

如果文件中没有任何内容,我会得到:

 <open file '<fdopen>', mode 'r' at 0xb77c1e90> A Traceback (most recent call last): File "<string>", line 1, in <module> IOError: [Errno 11] Resource temporarily unavailable 

…所以我们必须在try块中运行这个函数来捕获IOError ,如果文件中没有任何东西…( os.readf.read都会引发这个异常)