【问题标题】:Looping over with open() thows IOError循环使用 open() 抛出 IOError
【发布时间】:2014-08-20 10:00:31
【问题描述】:

我正在遍历多个数据库记录并将数据从它们各自的 BLOB 字段写入文件:

def build(self, records):
    """
    Builds openimmo.anhang
    """
    result = None
    anh_records = [r for r in records if type(r) == anhaenge]
    if not anh_records:
        return result
    anhang = []
    print('RECORDS: ' + str(len(anh_records)))
    for anh_record in anh_records:
        if anh_record.daten:
            __, path = mkstemp()
            with open(path, 'wb') as target:
                target.write(anh_record.daten)
            anh = openimmo.anhang()
            anh.anhangtitel = anh_record.anhangtitel
            anh.format = 'image/jpeg' #MIMEUtil.getmime(path)
            anh.daten = openimmo.daten()
            anh.daten.pfad = path
            anh.location = id2location.get(anh_record.location)
            anh.gruppe = id2gruppe.get(anh_record.gruppe)
            anhang.append(anh)
    try:
        result.validateBinding()
    except:
        self.log.err('Could not build "anhang": ' + str(result))
    if anhang:
        result = openimmo.anhaenge()
        result.anhang = anhang
    return result

然而,这会产生以下错误:

RECORDS: 5
Message: "[Errno 24] Too many open files: '/tmp/tmpo54qfq'
daemon panic:
Caught unexpected exception in _main() on 2014-08-20 11:53:37.918353
Message: "[Errno 24] Too many open files: '/tmp/tmpo54qfq'" of type "<class 'IOError'>"
Traceback (most recent call last):
  File "/usr/local/lib/python3.2/dist-packages/homie_core-1.0-py3.2.egg/homie/serv/daemon.py", line 345, in __run
  File "/usr/local/lib/python3.2/dist-packages/homie_core-1.0-py3.2.egg/homie/serv/service.py", line 72, in _main
  File "/usr/local/lib/python3.2/dist-packages/homie_core-1.0-py3.2.egg/homie/api/itf.py", line 127, in export
  File "/usr/local/lib/python3.2/dist-packages/homie_openimmodb-0.2_indev-py3.2.egg/openimmodb/itf.py", line 51, in _retrieve
  File "/usr/local/lib/python3.2/dist-packages/homie_openimmodb-0.2_indev-py3.2.egg/openimmodb/conv.py", line 27, in decode
  File "/usr/local/lib/python3.2/dist-packages/homie_openimmodb-0.2_indev-py3.2.egg/openimmodb/factories/openimmo/immobilie.py", line 60, in build
  File "/usr/local/lib/python3.2/dist-packages/homie_openimmodb-0.2_indev-py3.2.egg/openimmodb/factories/openimmo/anhaenge.py", line 30, in build
IOError: [Errno 24] Too many open files: '/tmp/tmpo54qfq'

根据lsof,整个进程有超过5k个打开文件:

# lsof| grep python3| wc -l
5375

我检查了几次:当我打开一个文件时,我在代码中的任何地方都使用了with open(file) as desc。 文件不应该在每个 with 块的末尾自动关闭,还是我遗漏了什么?

【问题讨论】:

    标签: file python-3.x io


    【解决方案1】:

    tempfile.mkstemp()为你打开一个文件:

    fd, path = mkstemp()
    with open(fd, 'wb') as target:
        # os.close(fd) is called automatically
    

    您不需要打开另一个文件(同名)的open(path)

    您可以使用tempfile.NamedTemporaryFile(delete=False) 代替tempfile.mkstemp()

    【讨论】:

    • 天啊,我怎么看不到这个。我刚刚在您回答后调查了 tempfile 模块以便更好地理解并找到mktemp()(没有's')。我想我会用这个——只是为了确定。谢谢。
    • @RichardNeumann:不要使用mktemp()(正如其文档所说)。 mkstemp()NamedTemporaryFile() 都应该没问题。后者直接返回targettarget.name是它的路径)。
    • @J.F.塞巴斯蒂安:再次感谢。我会仔细看看的。 PS:我的 exact 错误甚至记录在这里:logilab.org/17873 :-P
    • 因为我的答案中的代码显示您可以将 fd 直接传递给 open() 以获取文件对象,即 logilab 的修复会不必要地打开第二个文件。
    • 按照您的建议,我现在正在使用 NamedTemporaryFile()。
    猜你喜欢
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 2013-12-18
    相关资源
    最近更新 更多