Linux 在 Python 中超时读取文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21429369/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read file with timeout in Python
提问by sdaau
Within Linux, there is a file, /sys/kernel/debug/tracing/trace_pipe
, which as the name says, is a pipe. So, let's say I want to read the first 50 bytes from it using Python - and I run the following code:
在 Linux 中,有一个文件 ,/sys/kernel/debug/tracing/trace_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>
We can see that opening the file goes fast ( if we have the superuser permissions ) - however, if the trace_pipe
file is empty at that moment, it will simply block ( and even if there is content, the content will be dumped until there is no more, and then again the file will block ). Then I have to press Ctrl-Cto interrupt the Python script with a KeyboardInterrupt
...
我们可以看到打开文件的速度很快(如果我们有超级用户权限)——但是,如果此时trace_pipe
文件为空,它会简单地阻塞(即使有内容,内容也会被转储,直到没有更多,然后文件将再次阻塞)。然后我必须按Ctrl-C用KeyboardInterrupt
...
How can I have Python 2.7 do a read with timeout?
如何让 Python 2.7 进行超时读取?
That is, I want to instruct Python to "try read 50 bytes from this file; if you don't succeed after one second, give up and return"?
也就是说,我要指示Python “尝试从此文件中读取50个字节;如果一秒后不成功,则放弃并返回”?
采纳答案by Alfe
Use
用
os.read(f.fileno(), 50)
instead. That does not wait until the specified amount of bytes has been read but returns when it has read anything (at most the specified amount of bytes).
反而。这不会等到指定的字节数被读取,而是在读取任何内容(最多指定的字节数)时返回。
This does not solve your issue in case you've got nothingto read from that pipe. In that case you should use select
from the module select
to testwhether there is something to read.
如果您无法从该管道中读取任何内容,这并不能解决您的问题。在这种情况下,您应该使用select
from 模块select
来测试是否有要读取的内容。
EDIT:
编辑:
Testing for empty input with 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
回答by GabiMe
f = os.open("/sys/kernel/debug/tracing/trace_pipe", os.O_RDONLY|os.O_NONBLOCK)
Should prevent blocking (works in Unix only).. No need for select here..
应该防止阻塞(仅适用于 Unix)。这里不需要选择。
回答by sdaau
Just adding this as note, for better formatting:
只需将此添加为注释,以获得更好的格式:
@Alfe's answer in my case:
@Alfe 对我的回答:
$ 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() '
If there is something in the file, I get response like:
如果文件中有内容,我会得到如下响应:
<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
If there is nothing in the file, I get:
如果文件中没有任何内容,我会得到:
<open file '/sys/kernel/debug/tracing/trace_pipe', mode 'r' at 0xb7831e90>
[] [] []
timed out
Note that the select
documentation isn't explicit that the timeout
parameter is in seconds - but that floating point values (e.g. 0.5) also work.
请注意,select
文档并未明确说明timeout
参数以秒为单位 - 但浮点值(例如 0.5)也有效。
@GabiMe's answer:
@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() '
If there is something in the file, I get response like:
如果文件中有内容,我会得到如下响应:
<open file '<fdopen>', mode 'r' at 0xb77b6e90>
A bash-13777 [000] 13694.404519: sys_exi
B Timer-31065 [001] 13694.404830: sys_exi
If there is nothing in the file, I get:
如果文件中没有任何内容,我会得到:
<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
... so one must run this in a try
block, to catch the IOError
, if there is nothing in the file... (both os.read
and f.read
will raise this exception)
...所以必须在运行该try
块,赶上了IOError
,如果有什么文件中...(两者os.read
并f.read
会引发此异常)