Python:检查文件是否被锁定

15

我的目标是要知道一个文件是否被其他进程锁定,即使我没有访问该文件的权限!

更清楚地说,假设我使用Python内置的open()函数打开文件,并带有 'wb' 参数(用于写入)。如果:

  1. 用户没有文件的访问权限或者
  2. 文件被其他进程锁定,那么open()将会引发 IOError,并且errno 13 (EACCES)

那么如何在这里检测情况(2)呢?

(我的目标平台是Windows)


2
请检查该链接以了解如何使用Python在Linux中检查文件权限。 https://dev59.com/53I-5IYBdhLWcg3wbHq- - monkut
1
一旦您确定用户具有权限,但仍然出现异常,则知道已触发情况(2)。 - monkut
你知道其他进程是如何锁定文件的吗?看起来有多种方法可以实现。 - Sam Mussmann
假设您得到了这个问题的答案,您打算如何处理这些信息? - Karl Knechtel
1
@KarlKnechtel 向用户报告正确的响应。 - Ali
3个回答

7

您可以使用os.access来检查访问权限。如果访问权限良好,则必须是第二种情况。


1
os.access 似乎是正确的方法,但在 Windows 上,os.access("myfile", os.R_OK) 返回 True,即使我没有权限访问该文件。 - Ali
2
@Ali - 你说得对。在Windows中,os.access不能返回正确的值。这是在python.org上的问题[http://bugs.python.org/issue2528]。它还提供了一个补丁,但我不确定是否容易应用该补丁。 - Harman
2
感谢您指出这个错误。显然,在Windows上使用win32security,可以轻松获取文件的ACL权限。 - Ali
4
十年后,Python的问题仍然未解决... - djvg

6

正如之前的评论建议的一样,os.access不能返回正确的结果。

但我在网上找到了另外一段代码,可以实现这个功能。关键是它尝试重命名文件。

来自:https://blogs.blumetech.com/blumetechs-tech-blog/2011/05/python-file-locking-in-windows.html

def isFileLocked(filePath):
    '''
    Checks to see if a file is locked. Performs three checks
        1. Checks if the file even exists
        2. Attempts to open the file for reading. This will determine if the file has a write lock.
            Write locks occur when the file is being edited or copied to, e.g. a file copy destination
        3. Attempts to rename the file. If this fails the file is open by some other process for reading. The 
            file can be read, but not written to or deleted.
    @param filePath:
    '''
    if not (os.path.exists(filePath)):
        return False
    try:
        f = open(filePath, 'r')
        f.close()
    except IOError:
        return True

    lockFile = filePath + ".lckchk"
    if (os.path.exists(lockFile)):
        os.remove(lockFile)
    try:
        os.rename(filePath, lockFile)
        sleep(1)
        os.rename(lockFile, filePath)
        return False
    except WindowsError:
        return True

这是一个有趣的解决方案,但对于大多数任务来说,一秒钟的睡眠时间太长了。 - Olejan
这是我第一次尝试,对我来说(有点)有效。在我的情况下,我想访问一个Excel文件。以只读模式打开它没有帮助。写模式会创建一个新的空文件,因此无法使用。追加模式可以工作!另外,可能更优雅的方法是搜索锁定文件。在这里你是正确的:在Windows中,如果是Excel文件,则有一个名为~$excelfilename.xlsx的隐藏文件。 - Meredith Hesketh Fortescue

3

根据文档:

errno.EACCES
    Permission denied
errno.EBUSY

    Device or resource busy

所以只需要这样做:
try:
    fp = open("file")
except IOError as e:
    print e.errno
    print e

从中找出errno代码,然后你就准备好了。

3
权限拒绝和文件正在使用时,errno 错误码相同。 - Ali
1
fp = open("file") 之后使用 fp.close(),我认为会更安全。 - Yuda Prawira

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接