遇到代码报错,too many file open , 网上搜索后,知道是打开的file太多。对于这个问题可以通过两种方法解决。
第一种方法:修改最大允许打开文件数量
在linux上可以通过以下代码查看允许打开的最大文件个数
ulimit -a
可以通过以下代码修改这个最大数,如把最大允许打开的文件个数修改为5000
ulimit -n 5000
第二种方法:检查代码,对代码进行针对性修改
通过检查代码,找到了file open 过多的原因,PIL Image open打开了太多的图片
一般利用Image open 可以打开图片,不需要close,在适当时机自动关闭图片。
如下代码,实现了读取图片并进行转换为灰度图
from PIL import Image
import numpy as np
pic = Image.open('./bird.jpg')
pic_l = pic.convert("L")
程序不报错,并运行良好
现在,我们主动关闭图片后再执行转换操作,代码入下
from PIL import Image
import numpy as np
fp = open('./bird.jpg','rb')
pic = Image.open(fp)
fp.close()
pic_l = pic.convert("L")
运行出错
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-15-68cd0b54ad08> in <module>()
4 pic = Image.open(fp)
5 fp.close()
----> 6 pic_l = pic.convert("L")
C:\Users\admin\Anaconda3\lib\site-packages\PIL\Image.py in convert(self, mode, matrix, dither, palette, colors)
839 return self.copy()
840
--> 841 self.load()
842
843 if matrix:
C:\Users\admin\Anaconda3\lib\site-packages\PIL\ImageFile.py in load(self)
189 decoder = Image._getdecoder(self.mode, decoder_name,
190 args, self.decoderconfig)
--> 191 seek(offset)
192 try:
193 decoder.setimage(self.im, extents)
ValueError: seek of closed file
出错原因是convert需要调用ImageFile中的load函数。不光是convert,save也需要调用ImageFile中的load函数,在close后再对打开的图片进行save的话会报同样的错误。
为了减少pic file打开的数量,同时又可以对主动close后的pic 进行convert,save等操作。我们可以在close之前把pic转换为numpy array类型,代码如下
from PIL import Image
import numpy as np
fp = open('./bird.jpg','rb')
pic = Image.open(fp)
pic_array = np.array(pic) # Convert to numpy array
fp.close()
pic = Image.fromarray(pic_array) # convert to Image type
pic_l = pic.convert("L")
pic_l.show()
运行正常
总结:
主动关闭 Image open 后会使作用在pic上的部分方法失效,因此在关闭之前可以先保存为numpy array类型,再通过Image.fromarray读取图片,一定要在关闭之前保存,关闭之后保存,程序会报错。错误如下:
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
C:\Users\admin\Anaconda3\lib\site-packages\PIL\Image.py in fromarray(obj, mode)
2166 typekey = (1, 1) + shape[2:], arr['typestr']
-> 2167 mode, rawmode = _fromarray_typemap[typekey]
2168 except KeyError:
KeyError: ((1, 1), '|O')
During handling of the above exception, another exception occurred:
TypeError Traceback (most recent call last)
<ipython-input-19-73b842ea9f66> in <module>()
8 # fp.close()
9 print(type(pic_array))
---> 10 pic = Image.fromarray(pic_array) # convert to Image type
11 pic_l = pic.convert("L")
12 pic_l.show()
C:\Users\admin\Anaconda3\lib\site-packages\PIL\Image.py in fromarray(obj, mode)
2168 except KeyError:
2169 # print typekey
-> 2170 raise TypeError("Cannot handle this data type")
2171 else:
2172 rawmode = mode
TypeError: Cannot handle this data type
虽然关闭之后也可以保存为numpy array 但是,在利用Image.fromarray 转换为Image格式时报错了。因此,一定要关闭之前保存为numpy array