可能重复:
文件对象在引用计数为零时是否自动关闭?
我读到需要关闭文件对象,但有人实际上可以提供一个非常简单的示例(代码示例),其中错误是由不关闭文件对象引起的吗?
可能重复:
文件对象在引用计数为零时是否自动关闭?
我读到需要关闭文件对象,但有人实际上可以提供一个非常简单的示例(代码示例),其中错误是由不关闭文件对象引起的吗?
如果您将数据写入文件并且最后您的输出文件不包含您写入的所有数据,您可能会观察到这种情况,因为该文件未正确关闭(并且其缓冲区已刷新)。
这是关于这个问题的一个相当新的例子 Python not writing full string to file。
请注意,这个问题并不是 Python 独有的,你也可能在其他语言中遇到这个问题(例如,我在 C 语言中遇到过不止一次)
如果您无法关闭文件,您是否在问 Python 是否会引发错误?那么答案是“不”。
如果您询问是否可能丢失数据,答案是“是”。
以此类推,如果您将钥匙留在点火装置中,警察会给您开罚单吗?不会。这种做法是否会增加您“丢失”汽车的几率?是的。
编辑:
好的,你问的是一个例子,而不是聪明的评论。这是一个示例,虽然有点做作,因为这样做比研究缓冲区大小的极端情况更容易。
好的:
fh = open("erase_me.txt", "w")
fh.write("Hello there!")
fh.close()
# Writes "Hello there!" to 'erase_me.txt'
# tcsh-13: cat erase_me.txt
# Hello there!tcsh-14:
坏的:
import os
fh = open("erase_me.txt", "w")
fh.write("Hello there!")
# Whoops! Something bad happened and my program bombed!
os._exit(1)
fh.close()
# tcsh-19: cat erase_me.txt
# tcsh-20: ll erase_me.txt
# -rw-r--r-- 1 me us 0 Jul 17 15:41 erase_me.txt
# (Notice file length = 0)
在某些操作系统上,将大量数据写入文件而不关闭它会导致 libc 将其删除时不会刷新数据,从而导致文件被截断。
我还要补充一点,如果您在长时间运行的进程中不关闭打开的文件,您最终可能会达到每个进程允许打开的最大文件数,在 Linux 系统中,可以使用命令检查默认限制ulimit -aH
。
注意:我所说的限制是每个进程的文件描述符限制,其中包括物理文件、套接字......
从技术上讲没有错误,但它会一直留在内存中,直到垃圾收集器关闭文件,这可能会对其他进程产生负面影响。您应该始终明确关闭文件描述符。
在处理文件对象时,最好使用 with 关键字。这样做的好处是文件在其套件完成后正确关闭,即使在途中引发异常也是如此。它也比编写等效的 try-finally 块短得多:
与 一起使用:
with open('test.txt', 'rb') as f:
buf = f.readlines()
您可能不会收到任何错误,在微不足道的情况下会出现异常,并且您的文件可能包含所有内容,但在现实世界的程序中很容易出现灾难性错误。
python 的原则之一是“应该阻止但不禁止不良行为”,所以我建议始终专注于在“finally”块中关闭文件。
假设您正在处理目录中的一堆文件。不关闭它们会占用大量内存,甚至可能导致程序耗尽文件描述符或其他资源。
我们希望 CPython 在没有对剩余文件的引用时关闭文件,但不能保证这种行为,如果有人试图在不使用引用计数的 Python 实现(如 Jython)上使用您的模块,他们可能会遇到奇怪的情况错误或垃圾收集时间过长