【问题标题】:How to avoid Python fileinput buffering [duplicate]如何避免Python文件输入缓冲[重复]
【发布时间】:2011-08-27 09:18:11
【问题描述】:

可能重复:
Setting smaller buffer size for sys.stdin?

我有一个 Python (2.4/2.7) 脚本,它使用 fileinput 从标准输入或文件中读取。它易于使用,并且除了一种情况外效果很好:

tail -f log | filter.py

问题是我的脚本缓冲了它的输入,而(至少在这种情况下)我想立即看到它的输出。这似乎源于 fileinput 在执行任何操作之前使用readlines() 获取其bufsize 的字节值。我尝试使用 1 的 bufsize,但它似乎没有帮助(这有点令人惊讶)。

我确实发现我可以编写这样不缓冲的代码:

while 1:
    line = sys.stdin.readline()
    if not line: break
    sys.stdout.write(line)

这样做的问题是我失去了文件输入功能(即它会自动打开传递给我的程序的所有文件,如果没有,它甚至可以自动解压缩输入文件)。

那么我怎样才能两者兼得呢?理想情况下,我不需要显式管理我的输入文件列表(包括解压缩),但在以“流式”方式使用时不会延迟输入。

【问题讨论】:

  • 关闭标准输入文件句柄并用buffering = 0重新打开它(我没试过,所以我不会把它作为答案发布)
  • 您可能会通过说 fileinput 使用 readlines() 来误解这种情况。默认情况下,readlines() 在到达 EOF 之前不会返回,而 'for line in fileinput.input():' 和 'for line in sys.stdin:' 最终会在缓冲足够的字符时返回一些内容。不过,如果 fileinput 传递了一个 bufsize 参数,您可能是对的。
  • 我刚刚提交了错误报告bugs.python.org/issue26290“fileinput 和 'for line in sys.stdin' 对输入缓冲进行了奇怪的嘲弄”,其中包括您观察到的行为。摘要:fileinput 在 2.7 和 3.4 中都损坏了,“for line in sys.stdin:”在 2.7 中损坏但在 3.4 中修复,readline 在 2.7 和 3.4 中都可以正常工作。

标签: python readline buffering file-io


【解决方案1】:

尝试运行python -u; man 说它将“强制标准输入、标准输出和标准错误完全无缓冲”。

您可以在 filter.py 的第一行更改 hashbang 路径。

【讨论】:

  • Note that there is internal buffering in xreadlines(), readlines() and file-object iterators ("for line in sys.stdin") which is not influenced by this option.
  • 是的,因为 tMC 所说的原因,这不起作用。不过我确实试过了。
  • 那么不要使用基于行的 I/O。使用普通的stdin.read()
  • readline() (单数)工作得很好。只有 readlines() (复数)可以做我不想要的缓冲。我想 raw read() 也可以,但在这种情况下没有必要。
【解决方案2】:

你试过了吗:

def hook_nobuf(filename, mode):
    return open(filename, mode, 0)

fi = fileinput.FileInput(openhook=hook_nobuf)

未对其进行测试,但通过阅读 openhook 参数的作用以及传递 0 以打开 bufsize 参数,这应该可以解决问题。

【讨论】:

  • 这没有效果。同样,问题似乎是 fileinput 使用 readlines() 方法和内部缓冲区。
  • 好吧,我想这就是你的答案。要么不使用 fileinput,要么以 fileinput.py 为基础,将其重写为内部不缓冲。查看代码,似乎没有任何方法可以使其仅通过向其传递参数来至少进行一些缓冲。
  • 我是 Python 新手;这个用例没有被很好地涵盖似乎令人震惊(毕竟,如果不是为了这个,用 Python 编写文本过滤器似乎很自然)。
猜你喜欢
  • 2013-02-07
  • 2020-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-04
  • 1970-01-01
  • 2021-07-27
  • 1970-01-01
相关资源
最近更新 更多