如何在python中只删除文件的内容

Posted

技术标签:

【中文标题】如何在python中只删除文件的内容【英文标题】:How to delete only the content of file in python 【发布时间】:2013-06-12 03:19:57 【问题描述】:

我有一个包含一些内容的临时文件和一个为该文件生成一些输出的 python 脚本。我希望这重复 N 次,所以我需要重用该文件(实际上是文件数组)。我正在删除整个内容,因此临时文件在下一个周期中将为空。对于删除内容,我使用以下代码:

def deleteContent(pfile):

    pfile.seek(0)
    pfile.truncate()
    pfile.seek(0) # I believe this seek is redundant

    return pfile

tempFile=deleteContent(tempFile)

我的问题是:有没有其他(更好、更短或更安全)的方法来删除整个内容而不实际从磁盘中删除临时文件?

类似tempFile.truncateAll()

【问题讨论】:

第二次搜索确实是多余的。为什么不直接创建一个临时文件? 因为对于一个常见的脚本运行,我将需要大约 400 个临时文件而不是大约 10 个。所以我认为最好回收它们。我错了吗? 您遇到过实际问题吗?我只是创建新的临时文件,然后让 Python 和操作系统清理我关闭的文件。 实际上删除和关闭它们会是更多令人困惑的代码行。我的解决方案没有问题,我只需要了解更多方法并测试性能(同时让代码简单)。 如果您使用的是tempfile module,则无需删除任何内容。将临时文件用作上下文管理器 (with ...),它也会自动关闭。 【参考方案1】:

如何在python中只删除文件的内容

有几种方法可以将文件的逻辑大小设置为 0,具体取决于您访问该文件的方式:

清空打开的文件:

def deleteContent(pfile):
    pfile.seek(0)
    pfile.truncate()

清空一个文件描述符已知的打开文件:

def deleteContent(fd):
    os.ftruncate(fd, 0)
    os.lseek(fd, 0, os.SEEK_SET)

清空已关闭的文件(其名称已知)

def deleteContent(fName):
    with open(fName, "w"):
        pass


我有一个包含一些内容的临时文件 [...]我需要重用该文件

话虽如此,在一般情况下重用临时文件可能效率不高,也不可取。除非您有非常特殊的需求,否则您应该考虑使用 tempfile.TemporaryFile上下文管理器 几乎透明地创建/使用/删除您的临时文件:

import tempfile

with tempfile.TemporaryFile() as temp:
     # do whatever you want with `temp`

# <- `tempfile` guarantees the file being both closed *and* deleted
#     on the exit of the context manager

【讨论】:

pfile.truncate(0) 不会重置文件指针,因此无论哪种方式都需要pfile.seek(0)。同样适用于os.ftruncate()。 FWIW,您可以从pfile.fileno() 获取文件描述符,因此os.ftruncate(pfile.fileno(), 0) 可以工作,但之后您仍然需要执行pfile.seek(0) 来自docs.python.org/2/library/stdtypes.html#file.truncate Note that if a specified size exceeds the file’s current size, the result is platform-dependent: possibilities include that the file may remain unchanged, increase to the specified size as if zero-filled, or increase to the specified size with undefined new content. 这就是我没有这样做的原因。 @SylvainLeroux 对我来说不是。 f = open('foo', 'wb'); f.write('foo'); f.truncate(0); f.write('foo'); print f.tell() 打印 6. @SylvainLeroux 对我来说内容是"\x00\x00\x00\x00\x00Bonjour"。在foo 上执行xxd 进行检查。因此,实际上,您正在创建一个sparse file。 @SylvainLeroux 无论哪种方式,我都得到了领先的 NULL。 Linux 无论如何都会忽略b 标志。来自fopen(3)...“模式字符串还可以包含字母'b'作为最后一个字符或作为上述任何两个字符串中的字符之间的字符。这完全是为了与C89和没有效果;在所有符合 POSIX 的系统(包括 Linux)上都忽略了 'b'。"【参考方案2】:

我认为最简单的方法是简单地以写入模式打开文件然后关闭它。例如,如果您的文件 myfile.dat 包含:

"This is the original content"

那么你可以简单地写:

f = open('myfile.dat', 'w')
f.close()

这将删除所有内容。然后就可以将新的内容写入文件了:

f = open('myfile.dat', 'w')
f.write('This is the new content!')
f.close()

【讨论】:

【参考方案3】:

还有什么比这样更容易的呢:

import tempfile

for i in range(400):
    with tempfile.TemporaryFile() as tf:
        for j in range(1000):
            tf.write('Line  of file '.format(j,i))

这会创建 400 个临时文件并将 1000 行写入每个临时文件。它在我不起眼的机器上执行不到 1/2 秒。在这种情况下,当上下文管理器打开和关闭时,将创建和删除总计的每个临时文件。它快速、安全且跨平台。

使用tempfile 比尝试重新发明它要好得多。

【讨论】:

我认为没有 for 循环的 seek(0)truncate() 实际上更容易,更好,(也许更快),并且对 OS/python 更好 :) 我担心有人会被重用/recycling... 我的问题还是一样,所以这实际上不是答案。 你测试过这个假设吗?你有时间看吗?【参考方案4】:

你可以这样做:

def deleteContent(pfile):
    fn=pfile.name 
    pfile.close()
    return open(fn,'w')

【讨论】:

【参考方案5】:
with open(Test_File, 'w') as f:
    f.truncate(0)

我发现这种方法很简单。你可以试试这个。

【讨论】:

以上是关于如何在python中只删除文件的内容的主要内容,如果未能解决你的问题,请参考以下文章

如何从 python 中的字符串中只删除最后一个括号?

如何在 Python 中删除文件或文件夹?

如何删除文件夹的内容?

从 MKMapView 中只删除餐馆

在写入文件之前删除文件的内容(在 Python 中)?

Google Cloud Storage:如何在 Python 中(递归)删除文件夹