打开内部尝试 - 除了块,打开太多文件?

时间:2013-02-20 17:35:52

标签: python file exception with-statement

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

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块中,因为在少数情况下,打开的文件将为空,因此附加line.split()将导致索引错误,因为列表为空。

然而,当运行此脚本时,我收到以下错误:“OSError:[Errno 24]打开文件太多”

我的印象是“with open ...”声明的意思是它在使用后负责关闭文件?显然,这种情况并没有发生。

所以我要求的是两件事:

  1. 答案是:“我对开放的理解是否正确?”
  2. 如何更正导致此问题的错误?
  3. (是的,我知道代码并不完全优雅。整个尝试 - 除了应该是一个重用的单个对象 - 但我会在弄清楚这个错误后解决这个问题)

2 个答案:

答案 0 :(得分:1)

尝试将try-except移到with内,如此:

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

答案 1 :(得分:-1)

“打开的文件太多”与编写语义错误的python代码无关,而且正确使用with。关键是错误的一部分,即“OSError”,它指的是底层操作系统。

当你调用open()时,python解释器将执行系统调用。系统调用的细节因您使用的操作系统而有所不同,但在Linux上,此调用是打开的(2)。操作系统内核将处理系统调用。当文件打开时,它在系统文件表中有一个条目并占用操作系统资源 - 这意味着它在打开时有效地“占用空间”。因此,操作系统对任何时候都可以打开的文件数量有限制。

你的问题是,当你调用open()时,你不能足够快地调用close()。如果您的目录结构要求您同时打开数千个可能接近此上限的文件,则可以暂时更改(至少在Linux上,我对其他操作系统不熟悉,所以我不想去关于如何跨平台执行此操作的太多细节。)