如何在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中只删除文件的内容的主要内容,如果未能解决你的问题,请参考以下文章