【问题标题】:CSV, keep file open between each run/measurementCSV,在每次运行/测量之间保持文件打开
【发布时间】:2015-06-03 06:36:25
【问题描述】:

我有一个关于编写 CSV 文件的问题。我有一个仪器,我将每分钟读取一个值并将该值连同时间戳一起写入 CSV 文件。

我写了一个简单的代码,它是下面的第一个。但是我的朋友提出了一个问题:“为什么每次运行都打开和关闭文件。”我无法回答他的问题,因为我在编程和 Python 方面都是新手。尽管如此,我还是尝试重写代码,所以它变成了下面的解决方案 2,然后问我的朋友 是否更好,但他无法回答我。所以我希望你能帮助我,#1 和 #2 有什么区别,在之后读取文件时,两者给出的结果相同。

#1 会在 while 循环中为每次运行打开和关闭文件,而#2 会在最后一次运行后保持文件打开和关闭,这对吗?

这只是一个简单的示例,实际上,我将扩展代码,使其每分钟进行一次测量,运行 3-4 天,我将记录多个电压和最多 8 个温度。所以,最后,文件会变得很大,打开和关闭文件 可能会有点资源消耗。

代码 #1:

import csv
import datetime
import time

no_meas = 5 #number of measurements
cur_meas = 1    # current measurement number


while cur_meas <= no_meas:
    cur_time = datetime.datetime.strftime(datetime.datetime.now(), '%H:%M:%S')
    with open('test.csv', 'a', newline='') as fp:
        a = csv.writer(fp, delimiter=',')
        data = [[cur_time, 'test-text']]
        a.writerows(data)
    cur_meas += 1
    time.sleep(60)

代码 #2

import csv
import datetime
import time

no_meas = 5 #number of measurements
cur_meas = 1    # current measurement number

with open('test.csv', 'a', newline='') as fp:
    while cur_meas <= no_of_meas:
        cur_time = datetime.datetime.strftime(datetime.datetime.now(), '%H:%M:%S')
        a = csv.writer(fp, delimiter=csv_delimiter)
        data = [[cur_time, 'test-text']]
        a.writerows(data)
        cur_meas += 1
        time.sleep(60)

【问题讨论】:

  • 最好在codereview.stackexchange.com上问这个
  • 我认为你应该尽量避免打开-关闭操作,因为写-读的成本较低,也就是说它实际上取决于文件大小、操作量等,你也可以用它来计算每个代码的运行时间。
  • @Lutz Horn。好的,我会记住的。我不知道 codereview 存在。

标签: python csv writing


【解决方案1】:

如果您对文件的写入频率很高,您可能希望避免打开/关闭开销。尽管如此,从您的描述来看,这似乎不是一个问题(每分钟打开/关闭一次,用于编写几十个测量值)。即使几天后,您的文件也不应超过 1-3MB。

由于您打算让它运行几天,因此您应该在不丢失收集到的数据的情况下处理故障情况。在第一种情况下,您不会丢失任何数据。在第二种情况下,我建议在每次写入后添加一次刷新,以确保将数据写入磁盘:

a.writerows(data)
fp.flush()
os.fsync(fp.fileno())

【讨论】:

  • 在使用flush时我认为建议添加os.fsync(),以确保有一个完整的磁盘写入:)
  • @KobiK,是的,这将充分证明解决方案不会出现系统故障。我会更新答案。
  • @OernD,非常好的建议添加刷新。我已经添加了您编写的行,但我收到一条错误消息:AttributeError: '_csv.writer' object has no attribute 'flush'
  • @ThomasGundersen,对此感到抱歉。应在打开的文件而不是 csv 写入器上调用 flush()。修正了答案。
  • @OernD,它有效,但我在 os.fsync() 和参数数量上遇到错误。我在 fsync() 中尝试将 fp 作为参数,对吗?
猜你喜欢
  • 1970-01-01
  • 2011-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-09
  • 1970-01-01
相关资源
最近更新 更多