IOError:[Errno 24]打开的文件过多:

时间:2013-08-16 19:19:26

标签: python macos

我有一个巨大的文件,我写入大约450个文件。我收到错误too many files open。我在网上搜索并找到了一些解决方案,但它没有帮助。

import resource
resource.setrlimit(resource.RLIMIT_NOFILE, (1000,-1))
>>> len(pureResponseNames) #Filenames 
434
>>> resource.getrlimit(resource.RLIMIT_NOFILE)
(1000, 9223372036854775807)
>>> output_files = [open(os.path.join(outpathDirTest, fname) + ".txt", "w") for fname in pureResponseNames]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 24] Too many open files: 'icd9_737.txt'
>>> 

我还从命令行更改了ulimit,如下所示:

$ ulimit -n 1200
$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1200
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 709
virtual memory          (kbytes, -v) unlimited
$ 

我仍然遇到同样的错误。 PS:我也重新启动了我的系统并运行程序但没有成功。

6 个答案:

答案 0 :(得分:15)

“太多打开的文件”错误总是很棘手 - 您不仅需要使用ulimit,而且还必须检查系统范围限制和OSX特定。 This SO post gives more information on open files in OSX.(扰流警报:默认值为256)。

但是,通常很容易限制必须同时打开的文件数。如果我们看看Stefan Bollman的例子,我们可以很容易地将其改为:

pureResponseNames = ['f'+str(i) for i in range(434)]
outpathDirTest="testCase/"
output_files = [os.path.join(outpathDirTest, fname) + ".txt" for fname in pureResponseNames]

for filename in range(output_files):
    with open(filename, 'w') as f:
        f.write('This is a test of file nr.'+str(i))

答案 1 :(得分:4)

您可以考虑基于hard设置最大限制,而不是基于预定义的硬编码限制(如果尝试设置ValueError,则会抛出hard+1):

import resource
soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
resource.setrlimit(resource.RLIMIT_NOFILE, (hard, hard))

我想明确地说,删除python会话仍在运行时创建的文件并不重要,它仍然会引发此类错误。

认为这是每个python会话曾经创建(包括删除)的最大文件数。

答案 2 :(得分:3)

你应该尝试$ ulimit -n 50000而不是1200

答案 3 :(得分:0)

最小的工作示例会很好。我得到了与ron.rothman相同的结果,使用Python 3.3.2中的以下脚本,mac 10.6.8上的GCC 4.2.1。你使用它会出错吗?

    import os, sys
    import resource
    resource.setrlimit(resource.RLIMIT_NOFILE, (1000,-1))
    pureResponseNames = ['f'+str(i) for i in range(434)]
    try:
        os.mkdir("testCase")
    except:
        print('Maybe the folder is already there.')
    outpathDirTest="testCase/"
    output_files = [open(os.path.join(outpathDirTest, fname) + ".txt", "w") for fname in pureResponseNames]
    for i in range(len(output_files)):
        output_files[i].write('This is a test of file nr.'+str(i))
        output_files[i].close()

答案 4 :(得分:0)

sudo vim /etc/security/limits.conf

添加

*         hard    nofile      500000
*         soft    nofile      500000

到文件。

答案 5 :(得分:-1)

我强烈建议您不要增加ulimit

  1. 例如,您的数据库可能增长很多,导致 生成比以前更多的文件,以至于 变得大于您设定的限制,并认为足够了。
  2. 这是一项耗时/容易出错的维护任务,因为您会 必须确保每个环境/服务器都有该限制 正确设置且永不更改。

您应确保将openclose结合使用,或确保使用with语句(更具Python性)。

第三方库可能会给您带来问题(例如,pyPDF2 PdfFileMerger.append会保持文件打开状态,直到调用write方法为止)。 我跟踪此问题的方式非常难看,但是尝试在服务器上尝试一些操作同时监视打开的文件数量就达到了效果(我的本地开发计算机在Mac OS X上运行,服务器为CentO):

watch 'lsof | grep "something-created-filenames-have-in-common" | wc -l'