调用.close()后仍返回OSError: [Errno 9]错误的原因排查
文件描述符错误问题分析与解决
问题代码
def ldi(regAdress, value): buffer = open(regAdress, "w") buffer.write(bin(value)) buffer.close() def rdi(regAdress): buffer = open(regAdress, "r") print(int(buffer.read(10))) buffer.close()
问题现象
调用rdi()函数时抛出OSError: [Errno 9] Bad file descriptor,尽管ldi()中已经显式关闭了文件;尝试用try-finally重构代码时,又出现buffer未定义的错误。
原因分析
- 非普通文件的特殊限制:如果
regAdress指向的是系统设备文件(比如Linux寄存器节点、硬件设备文件),这类文件和普通磁盘文件逻辑不同,即使关闭了文件句柄,再次打开时可能因为设备本身的访问限制(如权限不足、设备锁定、读写模式不兼容)触发错误,而非之前的文件未关闭。 - try-finally的变量定义漏洞:如果
open()调用失败(比如文件不存在、权限不够),buffer变量根本不会被创建,此时finally块中调用buffer.close()自然会报未定义错误。
解决方法
1. 用with语句管理文件(推荐)
with语句会自动处理文件的打开与关闭,无论是否发生异常,都能确保文件被正确关闭,同时避免变量未定义的问题:
def ldi(regAdress, value): with open(regAdress, "w") as f: # bin()返回带0b前缀的字符串,直接写入文本模式文件即可 f.write(bin(value)) def rdi(regAdress): with open(regAdress, "r") as f: content = f.read(10) # 注意:bin写入的内容带0b前缀,转int需要指定基数为2 print(int(content, 2))
2. 修正try-finally的写法
如果一定要用try-finally,需要提前初始化buffer为None,并在finally中判断是否存在:
def ldi(regAdress, value): buffer = None try: buffer = open(regAdress, "w") buffer.write(bin(value)) finally: if buffer is not None: buffer.close() def rdi(regAdress): buffer = None try: buffer = open(regAdress, "r") content = buffer.read(10) print(int(content, 2)) finally: if buffer is not None: buffer.close()
3. 排查文件路径与权限
如果是设备文件,需要确认:
- 当前进程有足够的读写权限(可尝试用
sudo运行脚本) - 目标设备支持多次打开/读写操作(部分硬件寄存器文件可能需要特定的访问顺序或模式)
内容的提问来源于stack exchange,提问作者Alaric Truelove
相关产品推荐
相关产品推荐

