Python:重读文件的内容

时间:2013-06-11 14:36:11

标签: python file io refresh

我有一个应用程序每隔几秒更新一次的文件,我想在该文件中提取单个数字字段,并将其记录到列表中以供日后使用。所以,我想创建一个无限循环,其中脚本读取源文件,并且只要它注意到特定图形中的更改,它就会将该图形写入输出文件。

我不确定为什么我不能让Python注意到源文件正在改变:

#!/usr/bin/python

import re
from time import gmtime, strftime, sleep



def write_data(new_datapoint):
        output_path = '/media/USBHDD/PythonStudy/torrent_data_collection/data_one.csv'
        outfile = open(output_path, 'a')
        outfile.write(new_datapoint)
        outfile.close()


forever = 0
previous_data = "0"

while forever < 1:
        input_path = '/var/lib/transmission-daemon/info/stats.json'
        infile = open(input_path, "r")
        infile.seek(0)
        contents = infile.read()

        uploaded_bytes = re.search('"uploaded-bytes":\s(\d+)', contents)

        if uploaded_bytes:
                current_time = strftime("%Y-%m-%d %X", gmtime())
                current_data = uploaded_bytes.group(1)
                if current_data != previous_data:
                        write_data(","+ current_time + "$" + uploaded_bytes.group(1))
                        previous_data = uploaded_bytes.group(1)
                infile.close()
                sleep(5)
        else:
                print "couldn't write" + strftime("%Y-%m-%d %X", gmtime())
                infile.close()
                sleep(60)

现在,(凌乱)脚本正确写入一次,然后我可以看到虽然我的源文件(stats.json)文件正在发生变化,但我的脚本从不接受任何更改。它一直在运行,但我的输出文件没有增长。

我认为open()close()可以做到这一点,然后尝试投入.seek(0)

我缺少什么文件方法来确保python重新打开并重新读取我的源文件(stats.json)?

5 个答案:

答案 0 :(得分:2)

除非你正在实现一些同步机制或者可以保证某种原子读写,我认为你在这里要求竞争条件和微妙的错误。

想象一下“读者”访问文件而“作者”尚未完成其写周期。存在读取不完整/不一致数据的风险。在“现代”系统中,您还可以点击缓存 - 并且不会在附加时“实时”看到文件修改。

答案 1 :(得分:1)

我可以想到两种可能的解决方案:

  1. 你在无限循环的其他地方忘了关闭的括号 infile.close - &gt; infile.close()
  2. 正在更改JSON文件的程序没有关闭文件,因此它实际上没有更改。

答案 2 :(得分:1)

我看到两个问题:

  1. 您确定您的文件是否真的在文件系统上更新?我不知道你在使用你的代码操作系统是什么,但是如果文件没有被 producer 刷新,那么在这种情况下缓存可能会给你带来一个$$。
  2. 您的问题值得考虑 pipe 而不是文件,但是如果您的使用者消费者,那么我无法保证transmission在写入管道时会做什么死。
  3. 回答您的问题,请考虑使用以下方法之一:

    这些模块用于监视文件系统的更改,然后调用正确的操作。您的示例中的方法是原始的,具有较大的性能损失以及其他答案中已提到的其他问题。

答案 3 :(得分:1)

Ilya,检查( os.path.getmtime )是否有帮助,在处理文件之前是否更改了 stats.json

此外,我建议利用它是JSON文件的事实:

import json
import os
import sys

dir_name ='/home/klaus/.config/transmission/' 
# stats.json of daemon might be elsewhere

file_name ='stats.json'
full_path = os.path.join(dir_name, file_name)

with open(full_path) as fp:
    json.load(fp)
    data = json.load(fp)
    print data['uploaded-bytes']

答案 4 :(得分:0)

感谢所有的答案,不幸的是我的错误是在shell中,而不是在Python的脚本中。

问题的原因结果是我将脚本放在后台的方式。我正在做:Ctrl+Z我认为这会把任务放在后台。但它没有,Ctrl+Z只挂起任务并返回shell,后续bg命令是脚本在后台无限循环运行所必需的