打开已打开的文件不会引发异常

soe*_*ace 5 python io exception file

考虑这两个 python 程序:

script_a.py

from datetime import datetime
from time import sleep

while True:
    sleep(1)
    with open('foo.txt', 'w') as f:
        sleep(3)
        s = str(datetime.now())
        f.write(s)
        sleep(3)
Run Code Online (Sandbox Code Playgroud)

script_b.py

while True:
    with open('foo.txt') as f:
        s = f.read()
        print s
Run Code Online (Sandbox Code Playgroud)

运行script_a.py。在它运行时,启动script_b.py。两者都会愉快地运行,但script_b.py如果文件当前由script_a.py.

我期待引发IOError异常,告诉我文件已经打开,但它没有发生,相反文件看起来是空的。为什么会这样,检查它是否被另一个进程打开的正确方法是什么?是否可以简单地检查是否返回空字符串并重试直到读取其他内容,或者是否有更pythonic的方式?

mda*_*adm 3

请参阅有关 Python 中如何打开多个文件的其他答案和评论。如果您已阅读所有内容,但仍想锁定对 POSIX 平台上的文件的访问,那么您可以使用fcntl库。

请记住:A)其他程序可能会忽略您对文件的锁定,B)某些网络文件系统没有很好地实现锁定,或者根本没有实现锁定C)一定要非常小心地释放锁定并避免像flock那样死锁不会检测到它[1] [2]

示例.... script_a.py

from datetime import datetime
from time import sleep
import fcntl

while True:
    sleep(1)
    with open('foo.txt', 'w') as f:
        s = str(datetime.now())

        print datetime.now(), "Waiting for lock"
        fcntl.flock(f, fcntl.LOCK_EX)
        print datetime.now(), "Lock clear, writing"

        sleep(3)
        f.write(s)

        print datetime.now(), "releasing lock"
        fcntl.flock(f, fcntl.LOCK_UN)
Run Code Online (Sandbox Code Playgroud)

脚本_b.py

import fcntl
from datetime import datetime

while True:
    with open('foo.txt') as f:
        print datetime.now(), "Getting lock"
        fcntl.flock(f, fcntl.LOCK_EX)
        print datetime.now(), "Got lock, reading file"

        s = f.read()

        print datetime.now(), "Read file, releasing lock"
        fcntl.flock(f, fcntl.LOCK_UN)

        print s
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!