0

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

我不确定为什么我不能让 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)文件正在更改,但我的脚本永远不会接受任何更改。它继续运行,但我的输出文件没有增长。

我认为 anopen()和 aclose()可以解决问题,然后尝试加入 a .seek(0)

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

4

5 回答 5

2

除非您正在实施某种同步机制或可以保证以某种方式进行原子读写,否则我认为您在这里要求竞争条件和细微的错误。

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

于 2013-06-11T14:48:43.813 回答
1

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

  1. 您忘记了无限循环 else 中结尾的括号。
    infile.close-->infile.close()
  2. 更改 JSON 文件的程序并未关闭该文件,因此它实际上并未更改。
于 2013-06-11T14:49:42.653 回答
1

我看到的两个问题:

  1. 你确定你的文件真的在文件系统上更新了吗?我不知道您在哪个操作系统上使用您的代码,但在这种情况下,如果文件没有被producer刷新,缓存可能会踢掉您的 a$$ 。
  2. 您的问题值得考虑管道而不是文件,但是如果您的消费者死了,我不能保证transmission如果它坚持写入管道会做什么。

回答您的问题时,请考虑使用以下方法之一:

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

于 2013-06-11T14:54:59.587 回答
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']
于 2013-06-11T15:59:44.143 回答
0

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

问题的原因原来是我将脚本放在后台的方式。我在做:Ctrl+Z我认为这会将任务置于后台。但它没有,Ctrl+Z只会暂停任务并将您返回到 shell,bg脚本在后台无限循环运行需要后续命令

于 2013-06-11T21:56:55.493 回答