通过rc.local启动的Python脚本写入文件时丢失首次写入
我正在使用一台树莓派,系统是Raspbian,版本是2014年1月的Debian Wheezy,还有Python 3。
我从rc.local启动一个Python脚本,这个脚本可以捕捉键盘输入并将其写入一个文件,而不需要登录。
如果脚本要写入的文件还没有创建,第一次键盘输入会在屏幕上显示,但不会写入文件。之后的输入就都能正常写入了。
当我以登录用户的身份从命令行运行代码时,一切都正常,第一行内容会如预期写入新文件。
来自Midnighter的编辑代码
#!/usr/bin/env python3.2
import sys
from datetime import datetime
def main():
f = open('/home/pi/cards.csv','r')
sim = f.read()
sim = sim.split('\n')
simSet = set(sim)
while True:
try:
log = open('logs', 'a')
puk = input() # text input, i.e., always a string
included = "true" if puk in simSet else "false"
print(included, puk)
log.write("{included: %s, time: %s, number: %s}, \n" % (included, datetime.now(), puk))
log.close()
except ValueError:
log.close()
main()
还有rc.local的内容
sudo python3 /home/pi/rf1
我刚在学习这个,请原谅我的执行不太好。
解决方案
我现在意识到我漏掉了一个重要的细节,就是一个cron任务在关闭和复制正在写入的文件。
我在这里找到了我的答案 Python的file.flush()到底在做什么?
我用file.flush()
替代了file.close()
,结果就正常了。
下面是代码:
#!/usr/bin/env python3.2
import sys
from datetime import datetime
def main():
f = open('/home/pi/cards.csv','r')
sim = f.read()
sim = sim.split('\n')
simSet = set(sim)
log = open('logs', 'a')
while True:
try:
puk = input() # text input, i.e., always a string
included = "true" if puk in simSet else "false"
print(included, puk)
log.write("{included: %s, time: %s, number: %s}, \n" % (included, datetime.now(), puk))
log.flush()
except ValueError:
log.flush()
main()
1 个回答
0
问题是我在运行一个定时任务,这个任务会把数据复制到另一个文件,而这个文件正在被Python程序写入。
第一次写入的时候,数据没有保存到文件里,因为这个文件正在被另一个程序访问。
下面的段落描述了当时发生的情况:
https://stackoverflow.com/a/7127162/1441620
首先,flush这个操作会把程序中暂时存储的数据写入到实际的文件中。通常来说,这意味着数据会从程序的缓冲区复制到操作系统的缓冲区。
具体来说,如果另一个进程正在打开同一个文件进行读取,它就能访问到你刚刚写入的那些数据。但是,这并不一定意味着这些数据已经“永久”存储在硬盘上。
我觉得@Midnighter也建议使用with
语句来打开和关闭文件,这样也能解决这个问题。
更新后的代码在问题的解决方案部分。