0

为了避免误删和删除错误,如何检测该文件是否被其他线程读取或者占用?
最好不要引入第三方的库,库太多会很麻烦。

vsvsvsvs 850
2013-12-22 提问
3 个回答
14

永远不要忘记:跨平台特性是Python的血液和命脉。

在Linux下进程正在使用的文件,是不妨碍其他进程去移动/删除/更名的。因为在Linux下由inode确定文件,inode和文件路径虽然存在对应关系,但本质上是分离的。删除了某进程正在使用的文件,则在该进程没有关闭之前,哪怕文件在目录结构中消失了,也仍然能被访问到,直到没有任何进程打开了这个文件(inode节点的使用者数量降为0)后才会真正删除。

这个机制是很多Linux程序可以实现不退出升级的理由:旧程序和依赖库,在旧程序关闭前总是能访问到,所以无需关闭。而下次启动时,程序和库正好就升级成了新的。——你是否习惯了Windows下升级总要“退出正在运行的所有程序”,而对这一点感到很不可思议呢?

删除操作能否执行,何时执行,说到底这依赖操作系统的实现,不需要Python在“前端”去做无谓的判断。

被Windows毒害的程序员们,醒醒吧,世界上有很多优秀的实现,你可以不用,但不得不知,更不能画蛇添足的去做出一些“对抗”它的举动。

任何不能进行文件操作的状况(例如:权限不许可、文件锁、磁盘满、IO错误等),在Python中都表示为一个异常。请尊重Python的实现方式,先做事,再捕获异常,最后处理。不要做任何无谓的提前判断——因为你有限的预防,绝对覆盖不了所有可能出现的问题!!!

1

inode 应该是没有记录进程使用者的数量的, 而是链接者的数量. linux 下删除操作确实是删除了 inode. 可以不退出升级是因为升级后的新文件是新的 inode, 之后通过文件名找到的是这个新的 inode.

hmgle · 2013年12月23日

展开评论
2

我不知道 python 有没有现成的关于这样功能的库, 但其实检测一个文件是否被一个进程打开是和语言没有关系的, 和操作系统有关. linux 上可以通过遍历所有的进程, 看每一个进程有没有打开你需要知道的文件. 这可以通过 lsof 得到.
题外话: 个人认为是没有必要检测一个文件是否被其他进程所使用的, 第一是因为你很难保证原子性, 你所知道的仅仅是过去的一个时刻的状态, 有可能你刚刚遍历后, 某个进程就在这个时刻把它关闭或者打开了. 第二这相当于干涉了另外的进程或者被另外的进程牵制, 这样的设计是不合理的. 如果你真的需要这样的功能, 数据库是一个更好的选择.

0

「为了避免误删和删除错误」?为什么删除一个正由另外的进程使用的文件是「误删」呢?为什么删除一个正由另外的进程使用的文件会造成「删除错误」呢?即使由此造成删除失败的话,也只有一个原因:你在使用 Windows。就算这样,删除失败有那么可怕吗,让你想方设法去避免?就像 @hmgle 说的,你只能取得过去某个时刻的信息,根本避免不了的

撰写答案

推广链接