如何打开一个文件进行读写,也被截断为0?
我试过了:
f = open(PATH, 'w+')
然而,我无法从文件中读取(f.read()
返回一个空字符串)。
此外:
f = os.fdopen(os.open(PATH, os.O_RDWR | os.O_TRUNC), 'r+')
与前面的代码相同。
答案 0 :(得分:11)
这是一个模式表:
mode-string | truncate? | create? | what's allowed
-------------+-----------+---------+----------------
r | no | no | reading (only)
w | yes | yes | writing (only)
a | no | yes | writing (only), auto-appends
r+ | no | no | read and write
w+ | yes | yes | read and write
a+ | no | yes | read and (auto-appending) write
请注意,缺少模式(“读取和非自动追加写入,不会截断但会创建”)。如果你想要那个,你必须使用os
函数。
(使用所有这些,将b
添加到模式序列的末尾以对字节进行操作。没有b
的行为取决于Python2与Python3以及universal_newlines
选项。 )
除了所有这些之外,在使用+
更新模式打开的任何文件上从“读取模式”切换到“写入模式”,反之亦然,在大多数情况下需要搜索操作。有关详情,请参阅this answer。
编辑:以下是为类Unix系统定义的打开文件的各种os
操作:
os.open(path, flags, mode)
path
参数非常明显,只有在创建文件时才使用mode
参数(因此如果省略os.O_CREAT
标志则可以省略) 。如果您提供mode
,则最常见的值为0666
,对应rw-rw-rw-
。用户的“umask”(请参阅os.umask
)将删除不需要的权限,例如,002
的umask会删除最终写入位,从而导致rw-rw-r--
,077
除了最初的rw-
之外,它除外。另外两种常见模式是0777
(rwxrwxrwx
表示可执行文件)和0600
(rw-------
表示用户私有文件,例如使用用户电子邮件时的临时文件)
flags
值应该包括os.O_RDONLY
,os.O_WRONLY
或os.O_RDWR
中的一个:打开(仅限),写入(仅限)或两者兼而有之。 / p>
对于这些,你可以添加 1 os.O_CREAT
,意思是“创建文件,如果它不存在”; os.O_TRUNC
,意思是“立即将文件截断为零字节”;和/或os.O_APPEND
,意思是“所有os级别的写操作在写入之前隐式地寻找当前的文件结尾”。可能(取决于操作系统风格)是更多标志,例如O_EXCL
,O_NDELAY
,O_NOFOLLOW
等。 (可能最常用且可靠的是O_EXCL
,这意味着“如果这会打开现有文件就会失败”,因此只有在与O_CREAT
结合使用时才真正有用。您可以创建一个新文件,您可以保证系统中没有其他协作进程也在使用。O_NOFOLLOW
标志(如果存在)在某些安全上下文中也很有用,以避免符号链接陷阱。)
在所有情况下,根据您在os
级别提供的读/写设置,即O_RDONLY
,O_WRONLY
或O_RDWR
- 如果您再打包使用os.fdopen
将文件描述符转换为Python流,您无法获得在open
时未授予自己的额外权限。您只能减去一些,即,您可以使用O_RDWR
打开,然后fdopen
将流打开为只读或只写。此外,在更新模式下使用fdopen
时,需要在不同I / O方向之间进行搜索或刷新操作的烦人限制仍然存在。
请注意,a
级别的fdopen
(追加)模式,如果完全符合,则“O_APPEND
模式”不如a
模式(或使用open
使用io.open
或O_APPEND
的模式,所有这些都会导致设置基础O_APPEND
模式。这主要与共享文件的协作进程有关:如果两个或多个此类进程使用O_WRONLY
打开文件,只要它们的写入“足够小”(详细信息随操作系统再次变化),它们的写入不会混在一起。如果文件只是作为O_RDWR
或O_APPEND
打开,则两个协作进程可以调用底层搜索函数,然后调用底层写入函数,但如果这两个函数相互竞争,则可能会覆盖另一个数据
(某些标记,包括fcntl
,可以使用import fcntl
(来自F_SETFL
)和|
参数关闭和打开。这是一个相对较晚的添加Python2。)
1 “添加”这里可能意味着文字添加,但使用按位或os.open(os.O_RDWR | os.O_CREAT | os.O_TRUNC, 0666)
操作更常规。也就是说,os.open(os.O_RDWR + os.O_CREAT + os.O_TRUNC, 0666)
,而不是{{1}}。
答案 1 :(得分:10)
如果要存储数据,请截断使用r+
:
with open(PATH,"r+") as f:
line = f.read()
f.seek(0)
f.truncate()