如何使用 Python 块读取文件
How to Block-Read a File with Python
我在这个 Python 领域相当陌生,想从 运行 时另一个程序写入的文件中读取。所以我的脚本应该在其他程序编写后立即读取一行。
这是我的:
#!/usr/bin/env python
import datetime
import os
import select
import sys
FILENAME = "/home/sjngm/coding/source/python/text.log"
with open(FILENAME, "r", encoding = "utf-8", errors = "ignore") as log:
print("blocks: " + str(os.get_blocking(log.fileno())) + " / fd: " + str(log.fileno()) + " / " + str(log))
while True:
os.pread(log.fileno(), 1, 0)
sel = select.select([log], [], [], 60000.0) #[0]
line = log.readline().replace("\n", "")
if line:
print(line)
else:
print("-" + str(datetime.datetime.now()), end = "\r")
# do something interesting with line...
text.log(现在它只是一个普通的文本文件,没有其他进程访问它):
line 1
line 2
line 3
最后一行末尾有没有\n
无所谓
输出:
[sjngm@runlikehell ~]$ python ~/coding/source/python/test.py
blocks: True / fd: 3 / <_io.TextIOWrapper name='/home/sjngm/coding/source/python/text.log' mode='r' encoding='utf-8'>
line 1
line 2
line 3
^CTraceback (most recent call last):
File "/home/sjngm/coding/source/python/test.py", line 16, in <module>
line = log.readline().replace("\n", "")
File "/usr/lib/python3.6/codecs.py", line 321, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
KeyboardInterrupt
[sjngm@runlikehell ~]$ uname -a
Linux runlikehell 4.14.53-1-MANJARO #1 SMP PREEMPT Tue Jul 3 17:59:17 UTC 2018 x86_64 GNU/Linux
[sjngm@runlikehell ~]$
所以它说启用了阻止。打印三行后,脚本继续运行并不断打印当前时间,没有任何停顿。
它实际上应该在 pread()
、select()
或 readline()
处暂停。或者事实上,在我不知道的任何其他命令中。
如何进行这项工作?
请注意,我不想将文件通过管道传输到脚本,因为我想稍后使用 curses,它的 getch()
在这种情况下不起作用。
这似乎并不常见。我现在正在做的是:
import subprocess
with subprocess.Popen([ "tail", "-10000f", FILENAME ], encoding = "utf-8", errors = "ignore", universal_newlines = True, bufsize = 1, stdout = subprocess.PIPE).stdout as log:
line = log.readline()
换句话说,我在脚本中打开管道,而不是通过管道到脚本。缓冲似乎是在 tail
中与 Popen
的参数 bufsize
相关的。 encoding
和 universal_newlines
允许 readline()
读取字符串而不是字节数组(有关详细信息,请参阅 Python's documentation)。
系统的 stdin
现在仍然可用,并且 curses
可以很好地处理 keyboard/mouse 事件。
我在这个 Python 领域相当陌生,想从 运行 时另一个程序写入的文件中读取。所以我的脚本应该在其他程序编写后立即读取一行。
这是我的:
#!/usr/bin/env python
import datetime
import os
import select
import sys
FILENAME = "/home/sjngm/coding/source/python/text.log"
with open(FILENAME, "r", encoding = "utf-8", errors = "ignore") as log:
print("blocks: " + str(os.get_blocking(log.fileno())) + " / fd: " + str(log.fileno()) + " / " + str(log))
while True:
os.pread(log.fileno(), 1, 0)
sel = select.select([log], [], [], 60000.0) #[0]
line = log.readline().replace("\n", "")
if line:
print(line)
else:
print("-" + str(datetime.datetime.now()), end = "\r")
# do something interesting with line...
text.log(现在它只是一个普通的文本文件,没有其他进程访问它):
line 1
line 2
line 3
最后一行末尾有没有\n
无所谓
输出:
[sjngm@runlikehell ~]$ python ~/coding/source/python/test.py
blocks: True / fd: 3 / <_io.TextIOWrapper name='/home/sjngm/coding/source/python/text.log' mode='r' encoding='utf-8'>
line 1
line 2
line 3
^CTraceback (most recent call last):
File "/home/sjngm/coding/source/python/test.py", line 16, in <module>
line = log.readline().replace("\n", "")
File "/usr/lib/python3.6/codecs.py", line 321, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
KeyboardInterrupt
[sjngm@runlikehell ~]$ uname -a
Linux runlikehell 4.14.53-1-MANJARO #1 SMP PREEMPT Tue Jul 3 17:59:17 UTC 2018 x86_64 GNU/Linux
[sjngm@runlikehell ~]$
所以它说启用了阻止。打印三行后,脚本继续运行并不断打印当前时间,没有任何停顿。
它实际上应该在 pread()
、select()
或 readline()
处暂停。或者事实上,在我不知道的任何其他命令中。
如何进行这项工作?
请注意,我不想将文件通过管道传输到脚本,因为我想稍后使用 curses,它的 getch()
在这种情况下不起作用。
这似乎并不常见。我现在正在做的是:
import subprocess
with subprocess.Popen([ "tail", "-10000f", FILENAME ], encoding = "utf-8", errors = "ignore", universal_newlines = True, bufsize = 1, stdout = subprocess.PIPE).stdout as log:
line = log.readline()
换句话说,我在脚本中打开管道,而不是通过管道到脚本。缓冲似乎是在 tail
中与 Popen
的参数 bufsize
相关的。 encoding
和 universal_newlines
允许 readline()
读取字符串而不是字节数组(有关详细信息,请参阅 Python's documentation)。
系统的 stdin
现在仍然可用,并且 curses
可以很好地处理 keyboard/mouse 事件。