Python中关闭文件很重要
引言
在使用 Python 操作文件时,很多人会使用上下文管理器来操作。例如:
with open("xx.txt", mode="w") as f:
f.write("Hello, World!")
该with
语句启动上下文管理器。在此示例中,只要上下文处于活动状态,上下文管理器就会打开文件xx.txt并管理文件资源。通常,缩进块结束或引发异常,文件将关闭。可能很多初学者都会被建议这样用,可是为什么要这样写程序才更健壮?或者说为什么一定要关闭文件?
从系统的角度看
系统限制进程打开的文件数
调用open()
打开文件时,会对操作系统进行系统调用,硬盘驱动器找到该文件并为读取或写入做好准备。然后,操作系统将返回一个无符号整数n, Python 进程进行系统调用并获取整数 n 作为文件句柄获得与文件关联的编号后,就可以进行读取或写入操作了。 操作系统限制任何单个进程可以拥有的打开文件的数量,这个可以使用工具 ulimit
查看, 或者直接修改 /etc/security/limits.conf 改变文件数限制。
为什么限制?突破限制会怎样
从操作系统的角度来看,任何达到限制的进程都可能会泄漏文件句柄以及其他资源。资源泄漏可能是由于不良的编程习惯或试图攻击系统的恶意程序造成的,操作系统为了保护系统的稳定而采取限制措施。另外,对于大多数应用程序来说,打开这么多文件是没有意义的。在一个硬盘驱动器上最多只能同时进行一次读取或写入操作。
比如你写了一个简单的文件上传服务,在服务中你需要将用户上传的文件保存在服务器上,如果你没有在写完文件后关闭文件,随着服务的时间变长,服务开启的文件会越来越多,最后你会得到这个报错, OSError: [Errno 24] Too many open files。
那能不能突破这个文件限制呢?那肯定是可以的,当然你必须知道你的服务为什么要开启这么多的文件,比如对于一个长连接服务,他可能要求单个实例要支撑数万的tcp链接(Linux中套接字也是文件),那这时候如果还采取默认的单进程开启文件数量限制可能就不合适了,你就需要修正 /etc/security/limits.conf 配置文件。
从稳定性的角度看
我们每次操作文件都去使用with来管理上下文,with
封装了 try…except…finally
编码范式,能在任何情况下(当然不包括断电)极大限度的帮你关闭文件。
但是如果我们不关闭文件,将会面临什么?比如下边的代码
import os
f = open("xxx.txt", mode="w")
f.write("Hello, world!")
os._exit(1) # 模拟程序异常退出
这段代码你确实可以找到 xxx.txt 文件,但是文件里边没有**Hello, world!**内容。
为每个写操作都去操作磁盘是很昂贵。出于这个原因,Python 默认是使用一个缓冲区来收集写操作。当缓冲区满时,或者文件被显式关闭时,缓冲区被刷新,写操作完成,这时候才会写入磁盘。
Python 进程完成后,操作系统会执行自己的清理,关闭进程打开的所有文件描述符。崩溃可能发生在多个级别,并会干扰操作系统的清理,使文件句柄悬空。在 Windows 上,悬空文件句柄可能会出现问题,打开文件的进程也会锁定它,另一个进程在关闭之前无法打开该文件。Windows 用户可能熟悉不允许您打开或删除文件的恶意进程。文件句柄泄漏和缓冲区中的内容丢失已经够糟糕的了,但是中断文件操作的崩溃也可能导致文件损坏。
总结
首先因为受系统的限制,我们不管用哪种语言编程,都要把不在使用的文件描述符关闭,一来避免因开启文件过多导致服务异常,二来及时关闭不用的文件描述符也能节约资源。
另外我们永远无法完全避免崩溃的影响,但是我们可以通过使用上下文管理器来减少崩溃带来的影响。
相关文章
Python for 循环中的下一项
发布时间:2023/04/26 浏览次数:179 分类:Python
-
本文讨论了 Python 中的 for 循环以及如何通过使用 for 循环和示例来跳过列表的第一个元素。
Python While 循环用户输入
发布时间:2023/04/26 浏览次数:148 分类:Python
-
我们可以在 while 循环中使用 input() 函数来输入数据,直到在 Python 中满足某个条件。
在 Python 中将整数转换为罗马数字
发布时间:2023/04/26 浏览次数:87 分类:Python
-
本篇文章将介绍在 Python 中将整数转换为罗马数字。以下是一个 Python 程序的实现,它将给定的整数转换为其等效的罗马数字。
在 Python 中将罗马数字转换为整数
发布时间:2023/04/26 浏览次数:144 分类:Python
-
本文讨论如何在 Python 中将罗马数字转换为整数。 我们将使用 Python if 语句来执行此操作。 我们还将探讨在 Python 中将罗马数字更改为整数的更多方法。
在 Python 中读取 gzip 文件
发布时间:2023/04/26 浏览次数:70 分类:Python
-
本篇文章强调了压缩文件的重要性,并演示了如何在 Python 中使用 gzip 进行压缩和解压缩。
在 Python 中锁定文件
发布时间:2023/04/26 浏览次数:141 分类:Python
-
本文解释了为什么在 Python 中锁定文件很重要。 这讨论了当两个进程在没有锁的情况下与共享资源交互时会发生什么的示例,为什么在放置锁之前知道文件状态很重要,等等
在 Python 中将 PDF 转换为文本
发布时间:2023/04/26 浏览次数:196 分类:Python
-
在本教程中,我们将学习如何使用 Python 使用 PyPDF2、Aspose 和 PDFminer 将 PDF 文档转换为文本文件。
在 Python 中创建临时文件
发布时间:2023/04/26 浏览次数:53 分类:Python
-
本文讲解了tempfile库函数的四个子函数:TemporaryFile、NamedTemporaryFile、mkstemp、TemporaryDirectory。 每个部分都提供了适当的程序,以简化对概念的理解。