我有两个脚本,一个在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
是一个浮点数,当我把它乘以长时间,我就失去了精度 – 通常误差小于10(即小于1毫秒)。 我当然可以修复我的程序,以便比较这个精确度内的数字,但我宁愿有相同的数字。
在这里有一个类似的问题: 如何在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开始,经过了100纳秒的时间间隔(CE)的世界标准时间(UTC)。 请参阅https://msdn.microsoft.com/zh-CN/library/system.datetime.tofiletimeutc(v=vs.110).aspx
所以,为了这个问题的任何人的利益。 其实,事实证明,我提到的问题, 如何在Windows中获得*更改文件时间? ,是有点误导,因为它提到一个晦涩的驱动程序访问只有函数ZwQueryInformationFile
,而有简单的GetFileTime
函数,你可以使用。 无论哪种方式,这些功能需要文件句柄,而这又需要调用CreateFile
和CloseHandle
和大量的文件(在我的情况下约一百万),这是相当昂贵的。 所以最后我用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