python - mkstemp 打开太多文件

标签 python subprocess

我在一个循环(超过 10 000 次)中使用 subprocess.run 来调用一些 java 命令。 像这样:

 import subprocess
 import tempfile

 for i in range(10000):
     ret = subprocess.run(["ls"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
     (_, name) = tempfile.mkstemp()
     with open(name, 'w+') as fp:
         fp.write(ret.stdout.decode())

但是,过了一段时间,我得到了以下异常:

Traceback (most recent call last):
  File "mwe.py", line 5, in <module>
    ret = subprocess.run(["ls"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
  File "/usr/lib/python3.5/subprocess.py", line 693, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.5/subprocess.py", line 947, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.5/subprocess.py", line 1454, in _execute_child
    errpipe_read, errpipe_write = os.pipe()
OSError: [Errno 24] Too many open files

我是否缺少关闭某些文件描述符的内容? 谢谢

最佳答案

mkstemp 返回一个已经打开 文件描述符 fd 后跟文件名。您忽略了文件描述符(您选择的名称 _ 表明您已明确选择忽略它),因此您忽略了关闭它。相反,您使用文件名第二次打开文件,创建一个文件对象,其中包含同一文件的第二个 文件描述符。无论您是否关闭第二个,第一个都会保持打开状态。

这是对 mkstemp 方法的修复:

 temporaryFiles = []
 for i in range(1000):
     ...
     fd, name = tempfile.mkstemp()
     os.write(fd, ... )
     os.close(fd)
     temporaryFiles.append(name)  # remember the filename for future processing/deletion

根据 Wyrmwood 在评论中的建议,更好的方法是:

 temporaryFiles = []
 for i in range(1000):
     ...
     with tempfile.NamedTemporaryFile(delete=False) as tmp:
         # tmp is a context manager that will automatically close the file when you exit this clause
         tmp.file.write( ... )
         temporaryFiles.append(tmp.name)  # remember the filename for future processing/deletion

请注意,mkstempNamedTemporaryFile 构造函数都有参数,可让您更具体地了解文件的位置 (dir) 和命名(前缀后缀)。如果您想保留这些文件,您应该指定 dir 以便将它们保留在默认临时目录之外,因为默认位置可能会被操作系统清理。

关于python - mkstemp 打开太多文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54150644/

相关文章:

python - 杀死 python ffmpeg 子进程会破坏 cli 输出

Python子进程获取 child 的输出

Python:子进程不写入输出文件

python - 数字的正则表达式,包括小数和斜线

python - 为什么使用 pip install requirements.txt 而不是 pip install ./?

python - 通过 pandas 重新格式化我的 csv 文件(将一组值转换为列,将另一组值与相应的值匹配)

python - subprocess.check_output 没有高内存使用

python - 使用带有自定义类的图形生成器作为节点

android - 为什么我使用 NDK 源代码获得 python 和 perl?

python - stdout 从 shell 获取之前多于 1 行的内容