考虑这两个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_a.py
当前打开文件,script_b.py
输出一个空字符串。
我期待一个IOError
异常被提出,告诉我文件已经打开,但它没有发生,而是文件看起来是空的。为什么会这样,检查它是否被另一个进程打开的正确方法是什么?简单地检查是否返回一个空字符串,然后再次尝试,直到读取到其他内容,或者有更python的方法吗?
查看其他关于在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
希望这对你有帮助!
你可以随意打开一个文件,只要操作系统不阻止你。这对于在一个文件中获取多个游标以进行复杂操作有时很有用。
script_b.py
认为文件为空的原因是文件为空:
with open('foo.txt', 'w') as f:
以w
模式打开文件会立即擦除(即截断)文件。在script_a
中,最初有3秒的间隙,其中文件完全是100%空的,这就是script_b
所看到的。
在调用f.write
后的下一个三秒间隙中,文件仍然是…可能是空的。这是由于缓冲——磁盘上的文件不能保证包含你用write
写入的所有内容,直到你使用close
(即退出上下文管理器块)或在文件句柄上手动调用flush
。
或者,您可以在非缓冲模式下打开,这样写入总是立即写入磁盘。
with open('foo.txt','w',0) as f:
#no buffering, f.write() writes immediately to disk