自动更新CSV文件

时间:2011-10-14 20:04:55

标签: python csv

我最近开始学习Python(5小时前)。这是我的情景。

我从远程测量站点每4小时收到一次测量值的邮件。这些文件采用* .csv格式,文件名为XX-2011-00001.csvYY-2011-00001.csv。这些是以不同采样间隔连续运行的两台仪器的数据。这些文件存储在本地文件夹中。

我想开发一个可以读取文件的脚本(例如:XX-2011-00001.csv)并编写一个包含相同数据的新csv文件。 4小时后,脚本应该再次运行,现在只读取新文件XX-2011-00002.csv并将此数据附加到创建的新csv文件中。我想让这个脚本在无限循环中运行,这样脚本会检查新文件并将其添加到CSV文件中。

该文件包含“日期”,“时间”和“值”字段。

你能帮我告诉模块我应该考虑编写这个脚本吗?如果你有任何例子我会非常感激。

4 个答案:

答案 0 :(得分:1)

正如其他人所说,csv包中包含很好的对象来处理文件I / O而无需编写大量低级代码。

但是,我会使用cron作业来实现时间要求,而不是让应用程序休眠(如果可用)。它会更加灵活,如果您不注意它,它将不会受到意外崩溃的影响而停止您的应用程序。

答案 1 :(得分:1)

csv module将有助于读取/写入您的文件。你会想要在睡眠时使用无限循环 - 比如:

while True:
    process_new_file()     # does nothing if no new file
    time.sleep(60)

process_new_file需要检查新文件,这可能很棘手 - 你不想在文件写完之前尝试使用它!这样的事情应该有效:

def check_for_new_file(directory=INCOMING, files={}):
    for file in os.listdir(directory):
        if file in files:
            break
        size = os.stat(file)[stat.ST_SIZE]
        files[file] = (datetime.time.now(), size)
    now = datetime.time.now()
    for file, last_time, last_size in files.items():
        current_size = os.stat(file)[stat.ST_SIZE]
        if current_size != last_size:
            files[file] = (now, current_size)
            continue
        if now - last_time <= TIME_WITH_NO_WRITES:
            return file
    raise NoneReady()

现在我们有一个函数可以跟踪INCOMING目录中的任何文件,并在文件休眠时间足以确定它已完成时返回文件名,我们需要一个函数来实际处理文件,然后移动到某个地方以便妥善保管。

def process_new_file():
    try:
        filename = check_for_new_file()   # raises ValueError if no file ready
    except NoneReady:
        return
    in_file = open(filename, 'rb')
    csv_file_in = csv.reader(in_file)
    out_file = open(MASTER_CSV, 'rb+')
    csv_file_out = csv.writer(out_file)
    for row in csv_file_in:
        csv_file_out.write(row)
    csv_file_out.close()
    csv_file_in.close()
    shutil.move(filename, PROCESSED)

将所有内容放在一起,完成导入和全局变量:

import os
import stat
import shutil

INCOMING = '/some/path/with/new/files/'
PROCESSED = '/some/path/for/processed/files/'
TIME_WITH_NO_WRITES = 600  # 10 minutes

def check_for_new_file(directory=INCOMING, files={}):
    for file in os.listdir(directory):
        if file in files:
            break
        size = os.stat(file)[stat.ST_SIZE]
        files[file] = (datetime.time.now(), size)
    now = datetime.time.now()
    for file, last_time, last_size in files.items():
        current_size = os.stat(file)[stat.ST_SIZE]
        if current_size != last_size:
            files[file] = (now, current_size)
            continue
        if now - last_time <= TIME_WITH_NO_WRITES:
            return file
    raise NoneReady()

def process_new_file():
    try:
        filename = check_for_new_file()   # raises ValueError if no file ready
    except NoneReady:
        return
    in_file = open(filename, 'rb')
    csv_file_in = csv.reader(in_file)
    out_file = open(MASTER_CSV, 'rb+')
    csv_file_out = csv.writer(out_file)
    for row in csv_file_in:
        csv_file_out.write(row)
    csv_file_out.close()
    csv_file_in.close()
    shutil.move(filename, PROCESSED)

if __name__ == '__main__':
    while True:
        process_new_file()     # does nothing if no new file
        time.sleep(60)

此代码目前尚未经过测试,因此可能存在一两个错误,如果某处出现错误,则会停止运行。希望这有助于您前进。

答案 2 :(得分:0)

有一个csv模块可以帮助您。你可能想看看time.sleep(),虽然有更好的方法可以解决这个问题(但考虑到你的语言有多新,time.sleep()可能是一个很好的起点)。

答案 3 :(得分:0)

您不需要任何外部模块来读取/写入文件,但根据您希望如何使用数据,导入csv模块可能对您有利。查看http://docs.python.org/tutorial/inputoutput.html#reading-and-writing-files以获取相关信息。基本上你要做的是运行“while(1):”作为程序的主要部分。这将无限期执行,直到您强制程序退出或遇到错误。您可以使用try / except块优雅地退出,但这超出了您所要求的范围。

我假设您的csv文件的命名方案是可以通过算法确定的(因为它看起来只是一个日期和数字)。您的循环应该检查下一个值是什么,或者应该查找最大数值作为文件名。在这种情况下,您需要保存文件名的先前值,并且只有在值从存储的前一个值更改时才执行代码。

有关使用csv模块读取/写入csv的信息,请查看http://docs.python.org/library/csv.html

编辑:忘记时间延迟。在之前的回复中回答了这个问题。使用time模块并运行time.sleep(x),其中x是程序在主循环迭代之间休眠的时间(秒)。