在Python中排序磁盘I/O错误
我该怎么区分“磁盘已满”的错误和“尝试写入只读文件系统”的错误呢?
我可不想把我的硬盘填满来测试这个 :)
我想知道怎么分别处理这两种错误,这样我的代码就可以在用户试图写入只读文件系统时给出一个提示,而在用户试图在已满的磁盘上写文件时又给出另一个提示。
2 个回答
在只读文件系统中,文件本身会被标记为只读。这意味着如果你试图用写入的方式打开一个只读文件(比如用 O_WRONLY
或 O_RDWR
),这个操作会失败。在类UNIX系统中,系统会返回一个错误代码 EACCES
,表示你没有权限。
>>> file('/etc/resolv.conf', 'a') Traceback (most recent call last): File "", line 1, in IOError: [Errno 13] Permission denied: '/etc/resolv.conf'
相对而言,如果你试图往一个已经满了的文件里写东西,可能会遇到 ENOSPC
的错误。这里的“可能”很重要;这个错误可能会在你调用 fsync
或 close
时才被发现。
>>> file(/dev/full, 'a').write('\n') close failed in file object destructor: IOError: [Errno 28] No space left on device
当你捕获到 IOError
错误时,比如在 Python 2.* 中使用 except IOError, e:
这样的写法,你可以查看 e.errno
来了解具体是什么类型的输入输出错误(不过,这种方式在不同操作系统之间可能不太一致)。
你可以查看 Python 标准库中的 errno 模块;如果你在一个只读文件系统上尝试写入文件(在一个合理的操作系统上),应该会得到 errno.EPERM
、errno.EACCES
,或者更好的是 errno.EROFS
(表示“只读文件系统”);如果文件系统是可读写的,但没有剩余空间,你应该会得到 errno.ENOSPC
(表示“设备上没有剩余空间”)。不过,你需要在你关心的操作系统上进行一些实验(用一个小的 USB 闪存驱动器填满它应该很简单;-)。
你不能根据 errno 使用不同的 except
子句——这些子句必须通过它们捕获的异常的 类别 来区分,而不是通过异常实例的属性来区分——所以你需要在一个 except IOError, e:
子句内部使用 if/else 或其他方式来处理不同的情况。