我在open()
函数的参数中看不到任何内容,它们允许指定文件的共享方式。因此我怀疑该文件将尽可能地被共享。具体做法是:
在我看来,这是最合乎逻辑的实施方式。我的假设是否正确?
更新:Martijn Pieters表示答案取决于操作系统。所以,为了这个问题,我的目标操作系统是Windows。
答案 0 :(得分:4)
Python在打开文件时在内部使用_wfopen()
(Python 2 open()
函数)或_wopen()
(Python 3和io.open()
),这两者都不允许指定任何共享标志。因此,共享被设置为默认值,并且该默认值似乎没有记录。
如果您想自己设置共享模式,如果要打开指定共享模式的文件,则必须使用msvcrt.open_osfhandle()
。
有一个patch in the Python issue tracker实现了sharing
模块,说明了如何执行此操作。 只是来自该补丁的开启者,有点简化,是:
import os
import msvcrt
import _winapi
CREATE_NEW = 1
CREATE_ALWAYS = 2
OPEN_EXISTING = 3
OPEN_ALWAYS = 4
TRUNCATE_EXISTING = 5
FILE_SHARE_READ = 0x00000001
FILE_SHARE_WRITE = 0x00000002
FILE_SHARE_DELETE = 0x00000004
FILE_SHARE_VALID_FLAGS = 0x00000007
FILE_ATTRIBUTE_READONLY = 0x00000001
FILE_ATTRIBUTE_NORMAL = 0x00000080
FILE_ATTRIBUTE_TEMPORARY = 0x00000100
FILE_FLAG_DELETE_ON_CLOSE = 0x04000000
FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000
FILE_FLAG_RANDOM_ACCESS = 0x10000000
GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
DELETE = 0x00010000
NULL = 0
_ACCESS_MASK = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
_ACCESS_MAP = {os.O_RDONLY : GENERIC_READ,
os.O_WRONLY : GENERIC_WRITE,
os.O_RDWR : GENERIC_READ | GENERIC_WRITE}
_CREATE_MASK = os.O_CREAT | os.O_EXCL | os.O_TRUNC
_CREATE_MAP = {0 : OPEN_EXISTING,
os.O_EXCL : OPEN_EXISTING,
os.O_CREAT : OPEN_ALWAYS,
os.O_CREAT | os.O_EXCL : CREATE_NEW,
os.O_CREAT | os.O_TRUNC | os.O_EXCL : CREATE_NEW,
os.O_TRUNC : TRUNCATE_EXISTING,
os.O_TRUNC | os.O_EXCL : TRUNCATE_EXISTING,
os.O_CREAT | os.O_TRUNC : CREATE_ALWAYS}
def os_open(file, flags, mode=0o777,
*, share_flags=FILE_SHARE_VALID_FLAGS):
'''
Replacement for os.open() allowing moving or unlinking before closing
'''
if not isinstance(flags, int) and mode >= 0:
raise ValueError('bad flags: %r' % flags)
if not isinstance(mode, int) and mode >= 0:
raise ValueError('bad mode: %r' % mode)
if share_flags & ~FILE_SHARE_VALID_FLAGS:
raise ValueError('bad share_flags: %r' % share_flags)
access_flags = _ACCESS_MAP[flags & _ACCESS_MASK]
create_flags = _CREATE_MAP[flags & _CREATE_MASK]
attrib_flags = FILE_ATTRIBUTE_NORMAL
if flags & os.O_CREAT and mode & ~0o444 == 0:
attrib_flags = FILE_ATTRIBUTE_READONLY
if flags & os.O_TEMPORARY:
share_flags |= FILE_SHARE_DELETE
attrib_flags |= FILE_FLAG_DELETE_ON_CLOSE
access_flags |= DELETE
if flags & os.O_SHORT_LIVED:
attrib_flags |= FILE_ATTRIBUTE_TEMPORARY
if flags & os.O_SEQUENTIAL:
attrib_flags |= FILE_FLAG_SEQUENTIAL_SCAN
if flags & os.O_RANDOM:
attrib_flags |= FILE_FLAG_RANDOM_ACCESS
h = _winapi.CreateFile(file, access_flags, share_flags, NULL,
create_flags, attrib_flags, NULL)
return msvcrt.open_osfhandle(h, flags | os.O_NOINHERIT)
答案 1 :(得分:2)
当文件打开进行写入时,其共享模式将拒绝后续打开操作以打开文件进行读写。
假。没有获得锁。您可以尝试使用两个不同的cmd窗口:
首先
python -c "import time; f = open('tst','wb'); f.write('1'); time.sleep(3); f.write('333'); f.close"
第二,第一次正在运行
python -c "with open('tst','wb') as f: f.write('22')"
在1333
文件中生成tst
。在第一次写入第一个脚本后,使用f.flush()
刷新写入会导致2333
。错过的数据会被\x00
字符替换,您可以查看它,例如将f.write('1')
替换为f.write('1'*10**6)