使用truncate

时间:2015-11-01 20:05:49

标签: python python-3.x

如何打开一个文件进行读写,也被截断为0?

我试过了:

f = open(PATH, 'w+')

然而,我无法从文件中读取(f.read()返回一个空字符串)。

此外:

f = os.fdopen(os.open(PATH, os.O_RDWR | os.O_TRUNC), 'r+')

与前面的代码相同。

2 个答案:

答案 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-之外,它除外。另外两种常见模式是0777rwxrwxrwx表示可执行文件)和0600rw-------表示用户私有文件,例如使用用户电子邮件时的临时文件)

flags值应该包括os.O_RDONLYos.O_WRONLYos.O_RDWR中的一个:打开(仅限),写入(仅限)或两者兼而有之。 / p>

对于这些,你可以添加 1 os.O_CREAT,意思是“创建文件,如果它不存在”; os.O_TRUNC,意思是“立即将文件截断为零字节”;和/或os.O_APPEND,意思是“所有os级别的写操作在写入之前隐式地寻找当前的文件结尾”。可能(取决于操作系统风格)是更多标志,例如O_EXCLO_NDELAYO_NOFOLLOW等。 (可能最常用且可靠的是O_EXCL,这意味着“如果这会打开现有文件就会失败”,因此只有在与O_CREAT结合使用时才真正有用。您可以创建一个新文件,您可以保证系统中没有其他协作进程也在使用。O_NOFOLLOW标志(如果存在)在某些安全上下文中也很有用,以避免符号链接陷阱。)

在所有情况下,根据您在os级别提供的读/写设置,即O_RDONLYO_WRONLYO_RDWR - 如果您再打包使用os.fdopen将文件描述符转换为Python流,您无法获得在open时未授予自己的额外权限。您只能减去一些,即,您可以使用O_RDWR打开,然后fdopen将流打开为只读或只写。此外,在更新模式下使用fdopen时,需要在不同I / O方向之间进行搜索或刷新操作的烦人限制仍然存在。

请注意,a级别的fdopen(追加)模式,如果完全符合,则“O_APPEND模式”不如a模式(或使用open使用io.openO_APPEND的模式,所有这些都会导致设置基础O_APPEND模式。这主要与共享文件的协作进程有关:如果两个或多个此类进程使用O_WRONLY打开文件,只要它们的写入“足够小”(详细信息随操作系统再次变化),它们的写入不会混在一起。如果文件只是作为O_RDWRO_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()