简体   繁体   English

一致地在python中读写文件

[英]Consistent reading and writing a file in python

I'm a Python beginner and facing the following : I have a script periodically reading a settings file and doing something according to those settings . 我是Python的初学者,面对以下问题:我有一个脚本定期读取设置文件并根据这些设置做一些事情。 I have another script triggered by some UI that writes the settings file with user input values. 我有另一个由某些UI触发的脚本,该UI用用户输入值写入设置文件。 I use the ConfigParser module to both read and write the file. 我使用ConfigParser模块读取和写入文件。

I am wondering if this scenario is capable of leading into an inconsistent state (like in middle of reading the settings file, the other script begins writing). 我想知道这种情况是否能够导致不一致的状态(例如在读取设置文件的过程中,另一个脚本开始写入)。 I am unaware if there are any mechanism behind the scene to automatically protect against this situations. 我不知道幕后是否有任何机制可以自动防御这种情况。

If such inconsistencies are possible, what could I use to synchronize both scripts and mantain the integrity of the operations ? 如果可能出现这种不一致的情况,我可以使用什么来同步两个脚本并保持操作的完整性?

I'm a Python beginner and facing the following : I have a script periodically reading a settings file and doing something according to those settings . 我是Python的初学者,面对以下问题:我有一个脚本定期读取设置文件并根据这些设置做一些事情。 I have another script triggered by some UI that writes the settings file with user input values. 我有另一个由某些UI触发的脚本,该UI用用户输入值写入设置文件。

There may be a race condition when the reader reads while the writer writes to the file, so that the reader may read the file while it is incomplete. 当读取器在写入器写入文件的同时进行读取时,可能会出现争用情况,以便读取器可以在文件不完整时读取文件。

You can protect from this race by locking the file while reading and writing (see Linux flock() or Python lockfile module ), so that the reader never observes the file incomplete. 您可以通过在读写时锁定文件来防止这种竞争(请参阅Linux flock()Python lockfile module ),以使读者永远不会观察到文件不完整。

Or, better, you can first write into a temporary file and when done rename it to the final name atomically. 或者,更好的是,您可以首先写入一个临时文件,完成后将其原子重命名为最终名称。 This way the reader and writer never block: 这样,读者和作家就不会阻塞:

def write_config(config, filename):
    tmp_filename = filename + "~"
    with open(tmp_filename, 'wb') as file:
        config.write(file)
    os.rename(tmp_filename, filename)

When the writer uses the above method no changes are required to the reader. 当作者使用上述方法时,读者无需进行任何更改。

When you write the config file write it to a temporary file first. 写入配置文件时,请先将其写入临时文件。 When it's done, rename it to the correct name. 完成后,将其重命名为正确的名称。 The rename operation ( os.rename ) is normally implemented as an atomic operation on Unix systems, Linux and Windows, too, I think, so there will be no risk of the other process trying to read the config while the writing has not been finished yet. 我认为,重命名操作( os.rename )通常也是在Unix系统,Linux和Windows上作为原子操作实现的,因此,在写入尚未完成的情况下,不会有其他进程尝试读取配置的风险然而。

There are al least two ways to address this issue (assuming you are on a unix-ish system): 至少有两种方法可以解决此问题(假设您使用的是Unix系统):

  • If you want to write, write to a temporary file first, then do something unix can do atomically , especially rename the temporary file into place. 如果要写入,请先写入一个临时文件 ,然后执行unix可以自动执行的操作 ,尤其是rename临时文件rename到位。

  • Lock the file during any operation, eg with the help of this filelock module. 在任何操作期​​间(例如,借助此Filelock模块) 锁定文件。

Personally, I like the first option because it utilizes the OS, although some systems have had problems with the atomicity: On how rename is broken in Mac OS X - another limitation: the rename system call can not rename files across devices. 就个人而言,我喜欢第一个选项,因为它利用了OS,尽管某些系统在原子性上存在问题: 关于Mac OS X中重命名的方式被打破 -另一个限制:重命名系统调用无法跨设备重命名文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM