gpt4 book ai didi

python - 来自不同进程的文件同时读/写操作 : working on Windows but not on Linux

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:13:24 25 4
gpt4 key购买 nike

我正在使用 .log 文件中的数据创建一个 SQLite 数据库。机器每次执行操作时都会更新日志文件。我在 Windows 中要做的是监视这个文件的变化,一旦它被修改 - 由机器通过串行通信在外部进行,但我通过在记事本中打开文件并添加新行来模拟这种行为 - 阅读新行并将数据放入数据库。

问题是当我尝试对我的 Linux 机器执行相同操作时,因为显然 python 程序即使在更新和保存后也看不到文件中的任何修改。尽管如此,如果我在程序中关闭并重新打开文件以重新读取它,修改就在那里(但我仍然无法检测到新的修改)。

我实际上已经在运行 Raspbian 的 Raspberry Pi 3 B+ 上测试了相同的代码,它按预期工作:检测到修改,toute de suite 并将数据添加到数据库中。

.log 文件的格式如下所示。

01  (PB)      008   Pa    6.01  bar         12/11/2055  07:25:17    
01 (PB) 008 Pa 6.01 bar 12/11/2055 07:26:39
01 (PB) 009 Pa 6.00 bar 12/11/2055 07:29:45

这是我使用的代码:

import re
import sqlite3
import os, time

if __name__=='__main__':
fd = open('putty.log', 'r')

# Ici on crée la base de données qui gardera les résultats des tests

connection = sqlite3.connect('banc_tests.db')
cursor = connection.cursor()

create_db = """
CREATE TABLE tests (
reference VARCHAR(15),
num_serie VARCHAR(15),
operation TINYINT,
resultat CHAR(2),
fuite SMALLINT,
unite VARCHAR(5),
pression FLOAT,
pUnite VARCHAR(5),
date DATE,
time TIME
);
"""

cursor.execute(create_db)

# Here we look for the testing bank frame's format with regular expressions
# For now we are ignoring all information about low pressure, PE test, etc.

while 1:
where = fd.tell() # Garde la position actuelle du curseur dans le fichier
line = fd.readline() # On lit la ligne suivante
if not line:
time.sleep(1)
fd.seek(where) #Si il n'y a rien à lire on retourne à la position précédente.
else:
# The ([\+\-]?\d*)\s*(\w*) segment in intended to ignore whitespaces in the faulty testing lines
# as well as to grab the leak pressure for ordinary tests. To change it back to the original
# version, it suffices to replace every * by a +.
print(line)
found = re.findall(r'^\s+(\d+)\s+\((\w+)\)\s+([\+\-]?\d*)\s*(\w*)\s+(\d+\.?\d+)\s+(\w+).*\s(\d+)/(\d+)/(\d+)\s+(\d+:\d+:\d+)', line)

# La commande findall retourne une tuple dans une liste, donc ici j'enlève la tuple et laisse
# juste la liste avec les éléments dedans.

if found:
temp = list(found[0])

insert_values = """
INSERT INTO tests (reference, num_serie, operation, resultat, fuite, unite, pression, pUnite, date, time)
VALUES ("{ref}", "{num_ser}", "{op}", "{res}", "{fuite}", "{unt}", "{pression}", "{pUnt}", "{date}", "{time}"); """

insert_command = insert_values.format(ref='', num_ser='', op=temp[0], res=temp[1], fuite=temp[2], unt=temp[3], pression=temp[4], pUnt=temp[5], date='{}-{}-{}'.format(temp[8], temp[7], temp[6]), time=temp[9])
cursor.execute(insert_command)

connection.commit()

我认为这是 open() 函数的阻塞行为的问题,所以我尝试将 os.O_NONBLOCK 标志与 fcntl 一起使用;但是,它没有用。

有没有人知道是什么导致了 Linux (Debian 10 Bluster) 和 Windows 之间的这种不同行为?我可以做些什么来解决 Linux 端的问题?

最佳答案

我做了一些研究,发现了问题所在。这是因为在编辑器中保存后文件的inode发生了变化。

您可以使用 vim 并设置 set backupcopy=yes 来防止这种行为 ( http://vimdoc.sourceforge.net/htmldoc/options.html#'backupcopy' )

要观察此行为,您可以使用 ls -li,它将向您显示文件的 inode

pawel@pawel-XPS-15-9570:~/test$ ls -li putty.log 
10263515 -rw-r--r-- 1 pawel pawel 87 wrz 5 14:10 putty.log
pawel@pawel-XPS-15-9570:~/test$ echo 'test' >> putty.log
pawel@pawel-XPS-15-9570:~/test$ ls -li putty.log
10263515 -rw-r--r-- 1 pawel pawel 92 wrz 5 14:14 putty.log
pawel@pawel-XPS-15-9570:~/test$ vim putty.log
pawel@pawel-XPS-15-9570:~/test$ ls -li putty.log
10263513 -rw-r--r-- 1 pawel pawel 97 wrz 5 14:14 putty.log
pawel@pawel-XPS-15-9570:~/test$

第一列是inode。正如您在 vim 编辑后看到的那样,它发生了变化,这就是您的脚本看不到这些变化的原因(因为编辑器覆盖了该文件)。

关于python - 来自不同进程的文件同时读/写操作 : working on Windows but not on Linux,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57800994/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com