python - 保持文件句柄打开的缺点?
问题描述
我正在解析一些 XML 并将数据写入不同的文件,具体取决于当前正在处理的 XML 元素。处理一个元素真的很快,写入数据也是。因此,文件需要经常打开和关闭。例如,给定一个巨大的file
:
for _, node in lxml.etree.iterparse(file):
with open(f"{node.tag}.txt", 'a') as fout:
fout.write(node.attrib['someattr']+'\n'])
这会起作用,但相对而言,打开和关闭文件会花费很多时间。(注意:这是一个玩具程序。实际上我写入文件的实际内容以及文件名是不同的。有关数据详细信息,请参阅最后一段。)
一种替代方法可能是:
fhs = {}
for _, node in lxml.etree.iterparse(file):
if node.tag not in fhs:
fhs[node.tag] = open(f"{node.tag}.txt", 'w')
fhs[node.tag].write(node.attrib['someattr']+'\n'])
for _, fh in fhs.items(): fh.close()
这将使文件保持打开状态,直到 XML 解析完成。有一些查找开销,但与迭代打开和关闭文件相比,这应该是最小的。
我的问题是,这种方法的缺点是什么,性能方面?我知道这会使其他进程无法访问打开的文件,并且您可能会遇到打开文件的限制。但是,我对性能问题更感兴趣。保持所有文件句柄打开是否会产生某种内存问题或处理问题?在这种情况下可能会发生过多的文件缓冲?我不确定,所以这个问题。
输入的 XML 文件最大可达 70GB 左右。生成的文件数量限制在 35 个左右,这与我在上述帖子中读到的限制相去甚远。
解决方案
您已经提到的明显缺点是,将需要大量内存来保持所有文件句柄处于打开状态,这当然取决于文件的数量。这是您必须自己进行的计算。并且不要忘记写锁。
否则的话,它并没有太大的问题,但如果采取一些预防措施会很好:
fhs = {}
try:
for _, node in lxml.etree.iterparse(file):
if node.tag not in fhs:
fhs[node.tag] = open(f"{node.tag}.txt", 'w')
fhs[node.tag].write(node.attrib['someattr']+'\n'])
finally:
for fh in fhs.values(): fh.close()
注意:在 python 中循环一个 dict 时,你得到的项目实际上只是键。我建议做for key, item in d.items():
或for item in d.values():
推荐阅读
- php - Laravel Artisan 命令 - “找不到类”
- reactjs - 如何为 React Gutenberg 属性分配 iframe url 查询参数值
- javascript - 使用 HtmlWebackPlugin 时如何在里面添加某些脚本标签和标签
- css - CSS。定位和溢出
- drupal-8 - 如何在 Drupal 8 中创建和保存用户配置文件字段?
- python - DRF - `write_only=True` 显示在响应模式中
- mysql - SQL 查询为多个 AND 条件返回 0 行
- mysql - Ubuntu 16.04 上的问题 - MySQL 5.7 - 拒绝所有新用户访问,不包括 root
- c# - HttpClient中有多少个连接
- ios - 如何使用 UISearchBar 过滤类型为 [[String:String]] 的数组并显示为 String