连续读取文件并将新行附加到列表 (python)

Reading file continuously and appending new lines to list (python)

我正在练习 python 中的文件读取内容。我有一个文本文件,我想要 运行 一个连续读取该文本文件并将新写入的行附加到列表中的程序。要退出程序并打印出结果列表,用户应按“输入”。

到目前为止我编写的代码如下所示:

import sys, select, os

data = []
i = 0

while True:

    os.system('cls' if os.name == 'nt' else 'clear')
    with open('test.txt', 'r') as f:
        for line in f:
            data.append(int(line))
            
    print(data)
    if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
        line_ = input()
        break

所以要跳出 while 循环 'enter' 应该按下。公平地说,我只是从这里复制粘贴了解决方案:Exiting while loop by pressing enter without blocking. How can I improve this method?

但是这段代码只是一次又一次地将所有行附加到我的列表中。 所以,假设我的文本文件包含以下行:

1
2
3

所以我的列表将看起来像 data = [1,2,3,1,2,3,1,2,3...] 并且在我按 enter 之前有一定的长度。当我添加一行(例如 4)时,它将变为 data = [1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,4...].

所以我在我的 append 命令之前寻找某种 if statement 以便仅附加新写入的行。但是我想不出简单的东西。

我已经得到了一些提示,即

  1. 不断检查文件大小,只读取新旧大小之间的部分。
  2. 跟踪行号并跳到下一次迭代中未附加的行。

目前,我想不出如何做到这一点。我尝试摆弄 enumerate(f)itertools.islice 但无法正常工作。希望得到一些帮助,因为我还没有采用程序员的思维方式。

再次打开时存储file position between iterations. This allows to efficiently fast-forward the file

data = []
file_position = 0

while True:
    with open('test.txt', 'r') as f:
        f.seek(file_position)  # fast forward beyond content read previously
        for line in f:
            data.append(int(line))
        file_position = f.tell()  # store position at which to resume

我可以让它在 Windows 上运行。首先,退出while循环和继续读取文件是两个不同的问题。我假设,退出 while 循环不是主要问题,并且因为您的 select.select() 语句在 Windows 上不起作用,我创建了一个带有 [= 的 exit-while 14=] 在 Ctrl-c 上触发的子句。 (这只是一种方法)。

你问题的第二部分是如何连续读取文件。好吧,不是通过在 while 循环中一次又一次地重新打开它,而是在 while 循环之前打开它。

然后,一旦文件被更改,就会读取有效行或无效行。我想这是因为 f 上的迭代有时可能发生在文件完全写入之前(我不太确定)。无论如何,很容易检查读取行。我再次为它使用了一个 try-except 子句,如果 int(line) 引发错误,它会捕获错误。

代码:

import sys, select, os

data = []

with open('text.txt', 'r') as f:
    try:
        while True:

            os.system('cls' if os.name == 'nt' else 'clear')
            for line in f:
                try:
                    data.append(int(line))
                except:
                    pass
                
            print(data)
    except KeyboardInterrupt:
        print('Quit loop')
print(data)