Python 使用open()打开文件时使用的共享模式
我在Python 使用open()打开文件时使用的共享模式,python,windows,Python,Windows,我在open()函数的参数中看不到允许指定文件共享方式的任何内容。因此,我怀疑该文件将尽可能被允许共享。具体而言: 打开文件进行读取时,其共享模式将允许后续打开操作打开文件进行读取,但不允许进行写入 打开文件进行写入时,其共享模式将拒绝后续打开文件进行读取或写入的操作 在我看来,这是最符合逻辑的实现。我的假设正确吗 更新:Martijn Pieters表示答案取决于操作系统。因此,为了回答这个问题,我的目标操作系统是Windows 打开文件进行写入时,其共享模式将拒绝后续打开文件进行读取或写入的
open()
函数的参数中看不到允许指定文件共享方式的任何内容。因此,我怀疑该文件将尽可能被允许共享。具体而言:
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')"
在tst
文件中的1333
中生成结果。使用f刷新写入。在第一个脚本中第一次写入之后,flush()将导致2333
。丢失的数据被替换为\x00
字符,您可以检查它,例如,在打开文件时,将第一个f.write('1')
替换为f.write('1'*10**6)
Python在内部使用(Python2open()
函数)或(Python3和io.open()
),两者都不允许指定任何共享标志。因此,共享被设置为默认值,默认值似乎没有被记录
如果您想自己设置共享模式,如果您想打开指定共享模式的文件,则必须使用
有一个实现共享
模块的示例,演示了如何执行此操作。该补丁的开场白稍微简化了一些,如下所示:
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)
这完全取决于操作系统;你有什么想法吗?@MartijnPieters我的目标操作系统是Windows。在Linux上,没有锁定,所以你可以打开阅读和写入任意次数。我不会将此作为回答,因为您说您正在使用Windows。相关:好的,但您知道最终传递给CreateFile
的是什么吗?是不是无论Python文件模式如何,它都是文件共享
读取
?未设置文件共享
标志。完全open()。如果未设置文件共享
标志,则以独占方式打开文件。这一切是否归结为一个事实,即底层CRT对共享一无所知?我的问题真的是关于\u wfopen()
的问题吗?我想是的。顺便说一句,io.open()
使用,并且这两个文档都对设置的共享模式保持沉默。很难相信Python不支持锁定和共享。