关闭使用fdopen的文件描述符

2 投票
1 回答
4483 浏览
提问于 2025-04-18 14:58

我从os.open获取了一个文件描述符,然后用with os.fdopen来使用它。请问,我需要做些什么来关闭这个文件描述符吗?下面的代码中出现的OSError让我觉得可能不需要做什么,但我在文档中找不到确认的信息。

fd = os.open(os.path.expanduser("~/Desktop/foo"), os.O_WRONLY)
with os.fdopen(fd, "wt") as file:
    pass
os.close(fd) # OSError: [Errno 9] Bad file descriptor

1 个回答

7

在Python 2和通常情况下的Python 3中,文件是通过fdopen打开的,这时C标准输入输出会管理文件描述符。当用fclose关闭文件时,底层的描述符也会被关闭。因此,文件会在with代码块结束时关闭。

Linux手册中关于 fdopen(3) 的说明是:

fdopen()函数将一个流与现有的文件描述符fd关联起来。流的模式(可以是“r”、“r+”、“w”、“w+”、“a”、“a+”中的一个)必须与文件描述符的模式兼容。新流的文件位置指示器被设置为属于fd的那个,同时错误和文件结束指示器被清除。模式“w”或“w+”不会导致文件被截断。文件描述符不会被复制,并且在通过fdopen()创建的流关闭时会被关闭。对共享内存对象应用fdopen()的结果是未定义的。


在Python 3中,os.fdopenopen内置函数的一个包装/几乎别名:

os.fdopen(fd, *args, **kwargs)

返回一个与文件描述符fd连接的打开文件对象。这是open()内置函数的别名,接受相同的参数。唯一的区别是fdopen()的第一个参数必须始终是一个整数。

open的文档中关于打开文件描述符的说明是:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

打开文件并返回相应的文件对象。如果文件无法打开,将引发OSError。

file是一个字符串或字节对象,给出要打开的文件的路径名(可以是绝对路径或相对于当前工作目录的相对路径),或者一个要包装的文件的整数文件描述符。(如果给定了文件描述符,当返回的I/O对象关闭时,它会被关闭,除非closefd被设置为False。)

因此,如果你想要在Python文件对象关闭时保持文件描述符打开,你可以这样做:

fd = os.open(os.path.expanduser("~/Desktop/foo"), os.O_WRONLY)
with os.fdopen(fd, "wt", closefd=False) as file:
    pass

# I/O object dissociated but fd valid
os.close(fd) # no error.

撰写回答