在内部打开try-except块的情况下,打开的文件太多



很简单,我循环浏览特定位置的所有子文件夹,并从三个不同的文件中收集一些数字。

def GrepData():
import glob as glob
import os as os
os.chdir('RUNS')
RUNSDir = os.getcwd()
Directories = glob.glob('*.*')
ObjVal = []
ParVal = []
AADVal = []
for dir in Directories:
    os.chdir(dir)
    (X,Y) = dir.split(sep='+')
    AADPath = glob.glob('Aad.out')
    ObjPath = glob.glob('fobj.out')
    ParPath = glob.glob('Par.out')
    try:
        with open(os.path.join(os.getcwd(),ObjPath[0])) as ObjFile:
            for line in ObjFile:
                ObjVal.append(list([X,Y,line.split()[0]]))
        ObjFile.close()
    except(IndexError):
        ObjFile.close()
    try:
        with open(os.path.join(os.getcwd(),ParPath[0])) as ParFile:
            for line in ParFile:
                ParVal.append(list([X,Y,line.split()[0]]))
        ParFile.close()
    except(IndexError):
        ParFile.close()
    try:
        with open(os.path.join(os.getcwd(),AADPath[0])) as AADFile:
            for line in AADFile:
                AADVal.append(list([X,Y,line.split()[0]]))
        AADFile.close()
    except(IndexError):
        AADFile.close()
    os.chdir(RUNSDir)

每个文件打开命令都被放在一个try-except块中,因为在少数情况下,打开的文件将是空的,因此由于列表是空的所以附加行.split()将导致索引错误。

然而,当运行这个脚本时,我得到了以下错误:"OSError:[Erno 24]打开的文件太多"

我的印象是,"with open…"语句的想法是,它负责在使用后关闭文件?显然,这并没有发生。

所以我想要的是两件事:

  1. 答案是:"我对开放的理解正确吗?"
  2. 我如何纠正导致此问题的任何错误

(是的,我知道代码并不完全优雅。整个尝试-除了应该是一个可重用的单个对象-但我会在解决这个错误后修复它)

尝试在with中移动try-except,如下所示:

with open(os.path.join(os.getcwd(),ObjPath[0])) as ObjFile:
    for line in ObjFile:
        try:
            ObjVal.append(list([X,Y,line.split()[0]]))
        except(IndexError): 
           pass

注意:不需要手动关闭文件,这就是with的作用。此外,如果使用相同的名称,则无需在导入中使用as os

"打开的文件太多"与编写语义不正确的python代码无关,并且您正确地使用了with。关键是错误中写着"OSError"的部分,它指的是底层操作系统。

当您调用open()时,python解释器将执行一个系统调用。系统调用的细节因您使用的操作系统而异,但在linux上,此调用是开放的(2)。操作系统内核将处理系统调用。当文件打开时,它在系统文件表中有一个条目,并占用操作系统资源——这意味着它在打开时实际上"占用了空间"。因此,操作系统对一次可以打开的文件数量有限制。

您的问题是,当您调用open()时,调用close()的速度不够快。如果您的目录结构要求您同时打开数千个文件,可能会达到这个上限,则可以临时更改(至少在linux上,我不太熟悉其他操作系统,所以我不想详细介绍如何跨平台执行此操作)。

相关内容

  • 没有找到相关文章