【问题标题】:Getting last change time in Python on Windows在 Windows 上获取 Python 的最后更改时间
【发布时间】:2016-07-21 15:28:47
【问题描述】:

我有两个脚本,一个在 Python 中,一个在 Powershell 中,用于获取和比较文件的最后修改。 Powershell中的一个使用:

$t = $f.LastWriteTime.ToFileTimeUtc()

这个时间对我来说很重要,我需要在 Python 中获取相同的信息。我正在使用 os.stat 并使用以下公式将 UNIX 时间戳转换为“Windows 文件时间”*:

statinfo = os.stat(file_name)
t = long(statinfo.st_mtime * 10000000L) + 11644473600L * 10000000L

但是,我遇到了舍入错误的问题。 st_mtime 是一个浮点数,当我将它相乘并转换为 long 时,我会失去精度——通常误差小于 10(即小于 1 毫秒)。我当然可以修复我的程序,以便它在此精度范围内比较数字,但我更愿意使用相同的数字。

这里有一个关于 SO 的类似问题:How do I get *change* file time in Windows? 我从中收集到我必须访问结构 FILE_BASIC_INFORMATION (http://msdn.microsoft.com/en-us/library/windows/hardware/ff545762(v=vs.85).aspx),但是我不知道如何在不使用 IronPython、PyWin 或类似 Python 的情况下做到这一点扩展名。有没有简单的方法(可能使用ctypes)来访问这些信息?

*Windows 文件时间是一个 64 位值,表示自公元 1601 年 1 月 1 日午夜 12:00 (C.E.) 协调世界时 (UTC) 以来经过的 100 纳秒间隔数。见https://msdn.microsoft.com/en-us/library/system.datetime.tofiletimeutc(v=vs.110).aspx

【问题讨论】:

    标签: python windows ctypes


    【解决方案1】:

    因此,为了任何有此问题的人的利益。实际上,事实证明我提到的问题How do I get *change* file time in Windows? 有点误导,因为它提到了一个晦涩的驱动程序访问专用函数ZwQueryInformationFile,而您可以使用普通的GetFileTime 函数。无论哪种方式,这些函数都需要文件句柄,而这又需要调用CreateFileCloseHandle 并且对于大量文件(在我的情况下约为一百万),这非常昂贵。所以最后我使用了只需要路径的GetFileAttributesExW。根据我的测量,这仍然比 os.stat 慢一点(大约 10%),我认为这归因于通过 ctypes 调用函数的开销。

    所以在从互联网上复制粘贴后,我将以下代码放在一起,完全符合我的要求。

    from ctypes import windll, Structure, byref
    from ctypes.wintypes import LPWSTR, DWORD, FILETIME
    
    class WIN32_FILE_ATTRIBUTE_DATA(Structure):
        _fields_ = [("dwFileAttributes", DWORD),
                    ("ftCreationTime", FILETIME),
                    ("ftLastAccessTime", FILETIME),
                    ("ftLastWriteTime", FILETIME),
                    ("nFileSizeHigh", DWORD),
                    ("nFileSizeLow", DWORD)]
    
    filename = 'path and file name'
    
    wfad = WIN32_FILE_ATTRIBUTE_DATA()
    GetFileExInfoStandard = 0
    windll.kernel32.GetFileAttributesExW(LPWSTR(filename), GetFileExInfoStandard, byref(wfad))
    lowtime = long(wfad.ftLastWriteTime.dwLowDateTime)
    hightime = long(wfad.ftLastWriteTime.dwHighDateTime)
    filetime = (hightime << 32) + lowtime
    print filetime
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-18
      • 1970-01-01
      • 2011-12-09
      • 2018-07-20
      • 2010-09-27
      相关资源
      最近更新 更多