【发布时间】:2013-01-24 20:58:30
【问题描述】:
我似乎记得在较低级别的语言中,在程序中多次打开文件可能会导致共享查找指针。通过在 Python 中搞乱一点,这对我来说似乎没有发生:
$ cat file.txt
first line!
second
third
fourth
and fifth
>>> f1 = open('file.txt')
>>> f2 = open('file.txt')
>>> f1.readline()
'first line!\n'
>>> f2.read()
'first line!\nsecond\nthird\nfourth\nand fifth\n'
>>> f1.readline()
'second\n'
>>> f2.read()
''
>>> f2.seek(0)
>>> f1.readline()
'third\n'
这种行为是否安全?我很难找到一个消息来源说没关系,如果我能依赖这个,那将有很大帮助。
我没有将位置视为文件对象的属性,否则我对此更有信心。我知道它可以保存在迭代器内部,但不知道在这种情况下 .tell() 将如何获取它。
>>> dir(f1)
['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__',
'__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__str__', 'close', 'closed', 'encoding', 'fileno', 'flush',
'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline',
'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines',
'xreadlines']
更新
在The Python Essential Reference 的第 161 页上声明
同一个文件可以在同一个程序中多次打开(或在 不同的程序)。打开文件的每个实例都有自己的 可以独立操作的文件指针。
所以它实际上似乎是安全的、已定义的行为
【问题讨论】:
-
在python中每次调用
open()它都会创建一个新的文件对象(迭代器),所以你很安全。 -
我不知道有任何平台在这里维护不同的查找指针可能会遇到问题。但是……对于您的用例来说,您的代码可能会在某些情况下在 Windows 上引发打开
f2的异常,即使它在 Unix 上永远不会失败,这是否可以接受? -
@abarnert 我只希望它能够在 Windows 上运行,并且仅在阅读时运行。在windows上打开会正常获取排他锁吗?
-
@xhainingx:在 Unix 上,它要简单得多。 POSIX 定义了事情是如何工作的,基本上,即使特定的 Unix 确实具有 Windows 样式的锁定,也不允许在这里使用它。就像你可以在 4 个不同的终端中
tail -f foo并且它们不会相互干扰一样,你可以在 2 个线程中打开文件并读取它们,它们不会相互干扰。