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

时间:2014-03-24 18:16:17

标签: python file exception io

考虑这两个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)

script_b.py

while True:
    with open('foo.txt') as f:
        s = f.read()
        print s

运行script_a.py。在它运行时,启动script_b.py。两者都会愉快地运行,但如果文件当前由script_b.py打开,script_a.py会输出一个空字符串。

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

2 个答案:

答案 0 :(得分:2)

请参阅有关如何在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)

script_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

希望这有帮助!

答案 1 :(得分:1)

您可以根据需要多次打开文件,只要操作系统不会阻止您。这有时可以将多个游标放入文件中以进行复杂操作。

script_b.py认为文件为空的原因是文件 为空:

with open('foo.txt', 'w') as f:

w模式打开文件会立即擦除(即截断)文件。 script_a中存在最初的三秒间隙,其中文件完全100%为空,这就是script_b看到的内容。

在调用f.write后的 next 三秒间隙中,文件仍然是......可能为空。这是由于缓冲 - 磁盘上的文件无法保证包含您使用write写入的所有内容,直到您close(即退出上下文管理器块)或手动调用{{1}在文件句柄上。

或者,您可以在无缓冲模式下打开,以便始终立即将写入写入磁盘。

flush