2013-06-11 129 views
0

我有一个应用程序每隔几秒更新一次的文件,并且我想在该文件中提取单个数字段,并将其记录到列表中供以后使用。所以,我想在脚本读取源文件的地方进行无限循环,并且每当它发现某个特定图形发生变化时,就会将该图形写入输出文件。Python:重新读取文件的内容

我不知道为什么我不能让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)?

+0

“其他应用程序”超出了您的控制范围吗?有没有机会修改它的代码? –

+0

是的,它超出了我的控制范围。 – polpetti

回答

0

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

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

2

除非你正在实现一些同步机制,或者可以保证以某种方式进行原子读写,否则我认为你在这里调用竞态条件和微妙的错误。

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

+0

但是这个脚本怎么才第一次起作用呢?我正在阅读文件的次数多于其他应用程序正在更改的文件。 – polpetti

1

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

  1. 你忘了在括号中无限循环的其他密切。
    infile.close - >infile.close()
  2. 正在更改JSON文件的程序没有关闭该文件,因此实际上并未进行更改。
+0

1.修正了括号,这是一个错误2.在我的shell中,我可以'cat'文件的内容,并且每隔几秒就会看到它发生更改 – polpetti

1

两个问题我看到:

  1. 你确定你的文件确实是更新文件系统?我不知道你在用你的代码玩什么操作系统,但是在这种情况下,如果文件没有被生产者刷新,缓存可能会踢你的$$。
  2. 你的问题是值得考虑的而不是文件,但我不能保证什么transmission会做,如果它停留在如果你的消费者死写入管道。

回答你的问题,可以考虑使用以下之一:

这些模块是为了监控文件系统的变化,然后调用适当的行动。在你的例子中的方法是原始的,具有很大的性能损失,并且在其他答案中已经提到了其他问题。

+0

性能不是问题,运行在Raspberry pi上,'htop '说这个任务使用0.0%的CPU和1%的内存。这个脚本也是我想在机器上运行的少数几件事情之一。我会检查这些解决方法,谢谢。 – polpetti

1

伊利亚,这将有助于检查(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'] 
+0

是的,谢谢。 JSON提示非常有帮助。 – polpetti