在Python中读取带超时的文件

sda*_*aau 14 python linux python-2.7

在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>
Run Code Online (Sandbox Code Playgroud)

我们可以看到打开文件的速度很快(如果我们拥有超级用户权限) - 但是,如果该trace_pipe文件在那时是空的,它将只是阻塞(即使有内容,内容也将被转储,直到没有更多,然后再次文件将阻止).然后我必须按Ctrl- CKeyboardInterrupt... 中断Python脚本

如何让Python 2.7执行超时读取?

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

Alf*_*lfe 18

使用

os.read(f.fileno(), 50)
Run Code Online (Sandbox Code Playgroud)

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

如果您没有从该管道中读取任何内容,这并不能解决您的问题.在这种情况下,您应该使用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
Run Code Online (Sandbox Code Playgroud)

  • 关于如何使用select的信息,请参见我的编辑。select返回您交给它的流集的子集。您的情况很简单,只有一个流只想读取,因此将其他所有内容留空。给出一个0的超时值,这样它就永远不会等待任何事情,然后测试f是否可读。如果是这样,则至少可以读取一个字节。然后从该流中读取至少一个字节,最多读取50个字节(根据您的指定)。 (2认同)

Gab*_*iMe 12

f = os.open("/sys/kernel/debug/tracing/trace_pipe", os.O_RDONLY|os.O_NONBLOCK)
Run Code Online (Sandbox Code Playgroud)

应该防止阻塞(仅在Unix上工作)..不需要在这里选择..

  • 非常感谢,@ GabiMe; 不知道`os.open`提供平台特定选项!我想在这里移动接受,但我会继续第一个答案,因为使用这种方法,还需要知道`fdopen`,并且如果文件中没有任何内容也检查异常(参见我在下面的帖子中编辑).再次感谢 - 欢呼! (3认同)