【问题标题】:Python: Opening a file without creating a lockPython:打开文件而不创建锁
【发布时间】:2013-01-17 21:38:58
【问题描述】:

我正在尝试在 Python 中创建一个脚本来备份一些文件。但是,这些文件可以随时重命名或删除。我不希望我的脚本通过锁定文件来阻止这种情况;该文件应该可以在备份期间随时删除。

如何在 Python 中做到这一点?而且,会发生什么?如果无法读取流,我的对象会变为 null 吗?

谢谢!我对 Python 有点陌生。

【问题讨论】:

  • 行为取决于操作系统。您需要支持哪些操作系统?
  • 我认为您对此无能为力。如果文件在您阅读时被删除,您可能会收到一些IOErrorOSError(在python 中没有null 这样的东西。即使文件被删除,python 管理的文件对象也不是删除,并且在执行下一个系统(或 C)调用时会失败,从而引发异常)。
  • Python 上的普通open() 不会创建锁。此外,建议文件系统锁定不会阻止文件的删除或重命名,只能读取和写入(甚至这取决于应用程序正确使用flock())。
  • @FrancisAvila 这就是 Unix 上的情况,是的。在 Windows 上,打开的文件被“锁定”,因此无法删除(IIRC,CreateFile 有一个共享模式允许删除,但它有一些晦涩难懂的问题......)
  • @Bakuriu:如果您在删除文件之前打开它,从 Linux 中的已删除文件中读取它可以正常工作。

标签: python backup file-locking filestreams


【解决方案1】:

正如@kindall 所提到的,这是一个特定于 Windows 的问题。 Unix 操作系统允许删除。

要在 Windows 中执行此操作,我需要使用 win32file.CreateFile() 来使用特定于 Windows 的 dwSharingMode 标志(在 Python 的 pywin32 中,它只是称为 shareMode)。

粗略的例子:

import msvcrt
import os
import win32file

py_handle = win32file.CreateFile(
    'filename.txt',
    win32file.GENERIC_READ,
    win32file.FILE_SHARE_DELETE
        | win32file.FILE_SHARE_READ
        | win32file.FILE_SHARE_WRITE,
    None,
    win32file.OPEN_EXISTING,
    win32file.FILE_ATTRIBUTE_NORMAL,
    None
)
try:
    with os.fdopen(
        msvcrt.open_osfhandle(py_handle.handle, os.O_RDONLY)
    ) as file_descriptor:
        ... # read from `file_descriptor`
finally:
    py_handle.Close()

注意:如果您需要在返回的 文件句柄对象 的生命周期之后保持 win32-file 打开,则应调用PyHandle.detach() 在那个句柄上。

【讨论】:

  • 然后您可以使用os.fdopen(msvcrt.open_osfhandle(file_handle, os.O_RDONLY)) 将该句柄转换为标准文件对象。此外,os.fdopen() 也可以与with 一起使用,就像open() 一样。
【解决方案2】:

在包括 Linux 在内的类 UNIX 操作系统上,这不是问题。好吧,其他一些程序可能会在您读取文件的同时写入文件,这可能会导致问题(您正在复制的文件最终可能会损坏),但这可以通过验证通过来解决。

在 Windows 上,使用卷快照服务(又名卷影复制)。 VSS 会在某一时刻创建卷的快照,您可以在快照上打开文件,而无需锁定原始卷上的文件。一个快速的谷歌在这里找到了一个使用 VSS 进行复制的 Python 模块:http://sourceforge.net/projects/pyvss/

【讨论】:

  • 作为答案被接受,但我认为除了 VSS 之外我还需要一些东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多