通过rc.local启动的Python脚本写入文件时丢失首次写入

3 投票
1 回答
999 浏览
提问于 2025-04-18 06:23

我正在使用一台树莓派,系统是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语句来打开和关闭文件,这样也能解决这个问题。

更新后的代码在问题的解决方案部分。

撰写回答