使用Python PIL Image.open读取大量图片时候,遇到“OSError: [Errno 28] No space left on device”等问题,总结下问题:
1、“Too many open files”问题
原因:PIL的Image.open操作是lazy operation(类似Spark的tranform操作,即只是保存操作流程,需要调用action操作后才真正执行),即执行open之后,实际图片并未加载到内存;这时如果使用list推导表达式,那么后续在真正执行时候会同时打开大量图片,抛出Too many open files错误。
解决方案:在读取文件时候,主动调用action操作,将open后的对象copy到新对象,实现顺序读取、创建图片。
lst = []
for i in range(100000):
img=Image.open("***")
lst.append(img.copy())
img.close()
2、使用shufil.copy时候,运行中抛出OSError: [Errno 28] No space left on device
原因:使用和df -h和df -ih查看,发现瓷盘空间有剩余,但inodes已满,导致新文件的元数据无法存储。
解决方法:for i in /*; do echo $i; find $i | wc -l; done,查看各个目录下的文件数目,清楚文件,降低inodes的比例。
3、补充inodes的知识:
(1)文件在硬盘上存储时,最小存储单位Wie”扇区”(Sector),每个扇区储存512字节(相当于0.5KB)。OS读取硬盘为一次性连续读取多个扇区(多个扇区称为”块”(block),块是文件存取的最小单位,最常见是4KB,即连续八个 sector组成一个 block。。
(2)但是OS读取文件并不知道文件存储在哪里,通过通过文件的元数据才能知道,所以文件元数据也需要存储。每一个文件都有对应的inode,里面包含了与该文件有关的一些信息。
(3)文件元数据信息:文件的创建者、文件的创建日期、文件的大小等等。
(4)inode(索引节点):文件元数据存储的区域
-- over --