在Pillow中打开和加载图像时出现“打开的文件太多”错误。

14

当运行以下代码时:

KEEP=[]
for file in glob.glob("./KEEP/thing*.[tT][iI][fF]"):
    m = pattern.search(file)
    filename=m.group(1)
    keep=Image.open(file)
    keep.load()
    KEEP.append(keep)
    KEEP_NAMES.append(filename)
    keep.close()

在超过一千个文件中,我收到了错误消息:

Traceback (most recent call last):
  File "/hom/yannis/texmf/python/remove-harakat.py", line 123, in <module>
  File "/usr/local/lib/python2.7/dist-packages/PIL/Image.py", line 2237, in open
IOError: [Errno 24] Too many open files: './KEEP/thing1118_26.TIF'

我不明白为什么会发生这种情况,因为我已经使用load()函数加载了所有文件并使用close()函数关闭了它们,为什么它们还是保持打开状态呢? 除了减少文件数量之外(这对我来说不是选项),是否有其他解决方法?有没有一些方法可以在将文件内容读入内存后关闭它们?


无法在Python 3和最新的Pillow版本中重现。@yannis,请尝试运行此脚本http://pastebin.com/tP6E3UXE-问题是否还会出现? - alexanderlukanin13
应该是完全不需要 keep.close(),因为 keep.load() 应该在后台加载文件数据然后丢弃文件对象。也许它有一些副作用?我还在努力复现错误,但可以尝试删除 close 看看是否有帮助。 - KobeJohn
同时在Python 2.7.8或3.4.1和PILLOW 2.7.0中无法使用4000张图像进行复制。您确定这是实际死机的代码吗?我想知道您是否正在打开文件,将文件对象(而不是路径)提供给PIL,然后意外关闭Image而不是File Object...?我尝试过这样做,但还没有达到打开文件限制。 - KobeJohn
哪个版本的Pillow?什么操作系统?如果可以复现,请在此处打开问题:https://github.com/python-pillow/Pillow/issues/new - Hugo
1
我通过在shell上执行ulimit -n 2048来解决了这个问题(原本是1024,而这正好是pillow在崩溃之前打开的文件数)。 - yannis
我运行了alexanderlukanin13的脚本,它没有崩溃。如果有私信的方式,我会发送给您脚本文件和图片,以便重现问题。 - yannis
2个回答

18
这可能是使用Image.load方法时出现的一个bug,详情请参见Pillow问题 #1144。我也遇到了同样的too many open files错误,请参见# 1237
我的解决方法是将图像加载到临时对象中,进行复制,然后显式关闭临时对象。对于您的代码,解决方法应类似于此:
KEEP=[]
for file in glob.glob("./KEEP/thing*.[tT][iI][fF]"):
    m = pattern.search(file)
    filename = m.group(1)
    temp = Image.open(file)
    keep = temp.copy()
    KEEP.append(keep)
    KEEP_NAMES.append(filename)
    temp.close()

4

我也遇到了这个问题,并用稍微不同的方法解决了这个问题。

这个解决方法使用copy.deepcopy(),基于@indirectlylit的解决方案的类似逻辑,但避免了创建temp。请参见下面的代码片段。

import copy

KEEP=[]
for file in glob.glob("./KEEP/thing*.[tT][iI][fF]"):
    m = pattern.search(file)
    filename = m.group(1)
    keep = copy.deepcopy(Image.open(file))
    KEEP.append(keep)
    KEEP_NAMES.append(filename)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接