在 Windows Python 获取上次更改时间
Getting last change time in Python on Windows
我有两个脚本,一个在 Python 中,一个在 Powershell 中,用于获取和比较文件的最后修改。 Powershell 中的那个使用:
$t = $f.LastWriteTime.ToFileTimeUtc()
这次对我来说很重要,我需要在 Python 中获得相同的信息。我正在使用 os.stat
并使用以下公式将 UNIX 时间戳转换为 'Windows File Time'*:
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? from which I gather I would have to access the structure FILE_BASIC_INFORMATION (http://msdn.microsoft.com/en-us/library/windows/hardware/ff545762(v=vs.85).aspx),但是我不确定如果不使用 IronPython、PyWin 或类似的 Python 扩展该怎么做。是否有一种简单的方法(可能使用 ctypes
)来访问此信息?
*A Windows 文件时间是一个 64 位值,表示自 12:00 1601 年 1 月 1 日午夜 A.D 以来经过的 100 纳秒间隔的数量。 (C.E.) 协调世界时 (UTC)。参见 https://msdn.microsoft.com/en-us/library/system.datetime.tofiletimeutc(v=vs.110).aspx
因此,为了有此问题的任何人的利益。实际上,事实证明我提到的问题 How do I get *change* file time in Windows? 有点误导,因为它提到了一个晦涩的驱动程序访问功能 ZwQueryInformationFile
,而您可以使用简单的 GetFileTime
功能.无论哪种方式,这些函数都需要文件句柄,而这又需要调用 CreateFile
和 CloseHandle
并且对于大量文件(在我的情况下大约一百万),这是非常昂贵的。所以最后我使用了只需要路径的GetFileAttributesExW
。根据我的测量,这仍然比 os.stat
慢一点(大约 10%),我认为这是通过 ctypes
.
调用函数的开销所致
因此,在从 Internet 上进行一些复制粘贴后,我整理了以下完全符合我要求的代码。
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
我有两个脚本,一个在 Python 中,一个在 Powershell 中,用于获取和比较文件的最后修改。 Powershell 中的那个使用:
$t = $f.LastWriteTime.ToFileTimeUtc()
这次对我来说很重要,我需要在 Python 中获得相同的信息。我正在使用 os.stat
并使用以下公式将 UNIX 时间戳转换为 'Windows File Time'*:
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? from which I gather I would have to access the structure FILE_BASIC_INFORMATION (http://msdn.microsoft.com/en-us/library/windows/hardware/ff545762(v=vs.85).aspx),但是我不确定如果不使用 IronPython、PyWin 或类似的 Python 扩展该怎么做。是否有一种简单的方法(可能使用 ctypes
)来访问此信息?
*A Windows 文件时间是一个 64 位值,表示自 12:00 1601 年 1 月 1 日午夜 A.D 以来经过的 100 纳秒间隔的数量。 (C.E.) 协调世界时 (UTC)。参见 https://msdn.microsoft.com/en-us/library/system.datetime.tofiletimeutc(v=vs.110).aspx
因此,为了有此问题的任何人的利益。实际上,事实证明我提到的问题 How do I get *change* file time in Windows? 有点误导,因为它提到了一个晦涩的驱动程序访问功能 ZwQueryInformationFile
,而您可以使用简单的 GetFileTime
功能.无论哪种方式,这些函数都需要文件句柄,而这又需要调用 CreateFile
和 CloseHandle
并且对于大量文件(在我的情况下大约一百万),这是非常昂贵的。所以最后我使用了只需要路径的GetFileAttributesExW
。根据我的测量,这仍然比 os.stat
慢一点(大约 10%),我认为这是通过 ctypes
.
因此,在从 Internet 上进行一些复制粘贴后,我整理了以下完全符合我要求的代码。
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