【问题标题】:Reading file continuously and appending new lines to list (python)连续读取文件并将新行添加到列表(python)
【发布时间】:2020-07-07 13:26:18
【问题描述】:

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

到目前为止我写的代码是这样的:

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...] 并且有一定的长度,直到我按下回车键。当我添加一行(例如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,但无法使其工作。希望能得到一些帮助,因为我还没有采用程序员的思维方式。

【问题讨论】:

    标签: python list file-io


    【解决方案1】:

    在迭代之间存储file position。这允许在再次打开时有效地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
    

    【讨论】:

    • 谢谢,这正是我想要的!几天来一直在寻找一种方法来做到这一点,最终它比预期的要简单。我将研究seek()tell() 方法!
    • 也许您可以帮我解决另一个问题:是否可以同时对另一个文件执行该过程?所以说一个文件test2.txt,这些行被附加到列表data2
    【解决方案2】:

    我可以让它在 Windows 上运行。首先,退出while-loop和继续读取文件是两个不同的问题。我假设,退出while 循环不是主要问题,并且因为您的select.select() 语句在Windows 上不能以这种方式工作,所以我创建了一个带有try-except 子句的exit-while,该子句在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)
    

    【讨论】:

    • 谢谢,但这在我的 Mac 上不起作用。我想知道如何在 while 循环之前打开文件,因为当向文件写入新行并且文件已经被脚本打开时,它不会识别新写入的行还是我错了?退出 while 循环也不适合我。
    猜你喜欢
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 2020-08-25
    • 1970-01-01
    相关资源
    最近更新 更多