如何更改 Windows 文件的文件创建日期?
Posted
技术标签:
【中文标题】如何更改 Windows 文件的文件创建日期?【英文标题】:How do I change the file creation date of a Windows file? 【发布时间】:2011-06-27 03:41:13 【问题描述】:如何从 Python 更改 Windows 文件的文件创建日期?
【问题讨论】:
修改,访问次数可以被os.utime()
docs.python.org/library/os.html#os.utime修改
@Sebastian:感谢您的链接。我查看了 SO 问题,他们说没有独立于平台的方法,例如 linux 不存储文件创建时间
@David:很好,我会记住的。你为 cmets 做什么?
@Claudiu:我已经为那些在谷歌上搜索"python change file date windows"
的读者发布了它。您的问题是第二个链接。
Linux 的同样问题:***.com/q/887557/321973
【参考方案1】:
我的简单 和 clear filedate
模块可能会满足您的需求。
优点:
非常简单的界面 独立于平台 花式字符串日期支持 日期持有者实用程序安装
pip install filedate
用法
import filedate
Path = "~/Documents/File.txt"
filedate.File(Path).set(
created = "1st February 2003, 12:30",
modified = "3:00 PM, 04 May 2009",
accessed = "08/07/2014 18:30:45"
)
【讨论】:
【参考方案2】:如果您想输入日期而不是纪元,您可以获取此代码。我使用了 win32-setctime 和 attrs 包,所以首先安装:
pip install win32-setctime
pip install attrs
然后你就可以运行我的代码了,记得更新 FILEPATH、DATE、MONTH 和 YEAR。
from datetime import datetime
import attr
from win32_setctime import setctime
FILEPATH = r'C:\Users\jakub\PycharmProjects\date_creation_change\doc.docx'
DAY, MONTH, YEAR = (9, 5, 2020)
@attr.s
class TimeCounter:
"""
Class calculates epochs
"""
day = attr.ib(converter=str)
month = attr.ib(converter=str)
year = attr.ib(converter=str)
def create_datetime(self):
date_time_obj = datetime.strptime(r'//'.format(self.day,
self.month,
self.year), '%d/%m/%Y')
unix_start = datetime(1970, 1, 1)
return (date_time_obj - unix_start).days
def count_epoch(self):
days = self.create_datetime()
return days * 86400
@attr.s
class DateCreatedChanger:
"""
Class changes the creation date of the file
"""
file_path = attr.ib()
def change_creation_date(self):
epoch_obj = TimeCounter(day=DAY,
month=MONTH,
year=YEAR)
epoch = epoch_obj.count_epoch()
setctime(self.file_path, epoch)
if __name__ == '__main__':
changer = DateCreatedChanger(FILEPATH)
changer.change_creation_date()
【讨论】:
【参考方案3】:我不想将整个 pywin32
/ win32file
库仅仅用于设置文件的创建时间,所以我制作了 win32-setctime
包来实现这一点。
pip install win32-setctime
然后像这样使用它:
from win32_setctime import setctime
setctime("my_file.txt", 1561675987.509)
基本上,除了内置的ctypes
Python库之外,函数可以减少到几行,不需要任何依赖:
from ctypes import windll, wintypes, byref
# Arbitrary example of a file and a date
filepath = "my_file.txt"
epoch = 1561675987.509
# Convert Unix timestamp to Windows FileTime using some magic numbers
# See documentation: https://support.microsoft.com/en-us/help/167296
timestamp = int((epoch * 10000000) + 116444736000000000)
ctime = wintypes.FILETIME(timestamp & 0xFFFFFFFF, timestamp >> 32)
# Call Win32 API to modify the file creation date
handle = windll.kernel32.CreateFileW(filepath, 256, 0, None, 3, 128, None)
windll.kernel32.SetFileTime(handle, byref(ctime), None, None)
windll.kernel32.CloseHandle(handle)
有关高级管理(如错误处理),请参阅the source code of win32_setctime.py
。
【讨论】:
如果解释了幻数的含义,这段代码会更有用。我的猜测是: - 纪元是以秒为单位的时间?从何时起?也许没关系? - 10000000 是秒和 WIndows 的 100 ns 时间单位之间的转换因子 - 116444736000000000 是,好吧,我不知道。这似乎是一个大约 369 年的时间跨度,但我无法确定。 @BruceDawson 这来自 Microsoft 文档:How To Convert a UNIX time_t to a Win32 FILETIME or SYSTEMTIME。 谢谢。这有助于为一些神奇数字的含义提供上下文。在您的答案中记录它们仍然会很好,包括仍然无法解释的 1561675987.509 数字,我猜这只是一个随机选择的时间? @BruceDawson 当然,我在代码 sn-p 中添加了一些 cmets。 ;) GitHub 上的项目应该更新为使用kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
并通过raise ctypes.WinError(ctypes.get_last_error())
引发异常。这 (1) 将其与使用全局库加载器 ctypes.windll
的其他包隔离,后者缓存加载的库,缓存函数指针,以及 (2) 在 FFI 调用后立即可靠地捕获线程在 C 中的最后一个错误值。跨度>
【参考方案4】:
import os
os.utime(path, (accessed_time, modified_time))
http://docs.python.org/library/os.html
至少改变了修改时间,不使用win32模块。
【讨论】:
不幸的是,我很确定这只会改变文件修改时间和访问时间,而不是文件创建时间,正如 OP 所希望的那样。 在 XP 上至少它设置了创建时间。 在 XP 或 Win7 上对我没有任何作用,atime 设置访问时间,mtime 设置修改时间,既不设置创建时间。【参考方案5】:这是一个适用于 Python 3.5 和 windows 7 的解决方案。非常简单。我承认这是草率的编码......但它的工作原理。欢迎你清理它。我只需要一个快速解决方案。
import pywintypes, win32file, win32con, datetime, pytz
def changeFileCreationTime(fname, newtime):
wintime = pywintypes.Time(newtime)
winfile = win32file.CreateFile(fname, win32con.GENERIC_WRITE,
win32con.FILE_SHARE_READ |
win32con.FILE_SHARE_WRITE |
win32con.FILE_SHARE_DELETE,
None,
win32con.OPEN_EXISTING,
win32con.FILE_ATTRIBUTE_NORMAL,
None)
win32file.SetFileTime( winfile, wintime, wintime, wintime)
# None doesnt change args = file, creation, last access, last write
# win32file.SetFileTime(None, None, None, None) # does nonething
winfile.close()
if __name__ == "__main__":
local_tz = pytz.timezone('Antarctica/South_Pole')
start_date = local_tz.localize(datetime.datetime(1776,7,4), is_dst=None)
changeFileCreationTime(r'C:\homemade.pr0n', start_date )
【讨论】:
目录:见这里:***.com/questions/4998814/…!【参考方案6】:先安装pywin32扩展https://sourceforge.net/projects/pywin32/files/pywin32/Build%20221/
import win32file
import pywintypes
# main logic function
def changeFileCreateTime(path, ctime):
# path: your file path
# ctime: Unix timestamp
# open file and get the handle of file
# API: http://timgolden.me.uk/pywin32-docs/win32file__CreateFile_meth.html
handle = win32file.CreateFile(
path, # file path
win32file.GENERIC_WRITE, # must opened with GENERIC_WRITE access
0,
None,
win32file.OPEN_EXISTING,
0,
0
)
# create a PyTime object
# API: http://timgolden.me.uk/pywin32-docs/pywintypes__Time_meth.html
PyTime = pywintypes.Time(ctime)
# reset the create time of file
# API: http://timgolden.me.uk/pywin32-docs/win32file__SetFileTime_meth.html
win32file.SetFileTime(
handle,
PyTime
)
# example
changeFileCreateTime('C:/Users/percy/Desktop/1.txt',1234567789)
【讨论】:
为什么很难发现win32file
是pywin32
的一部分?谷歌让我兴奋不已,这意味着其他答案都毫无用处;他们假设您已经安装了它。感谢您在答案顶部提供的有用提示。
P.S.任何需要来自datetime
对象的时间戳的人都可以在这里找到答案:***.com/q/7852855/5987【参考方案7】:
这是已接受答案的更可靠版本。它还具有相反的吸气剂功能。这涉及创建、修改和访问的日期时间。它处理以 datetime.datetime 对象或“自纪元以来的秒数”(getter 返回的内容)形式提供的 datetimes 参数。此外,它会调整夏令时,而接受的答案不会。否则,当您在实际系统时间的相反阶段设置冬季或夏季时间时,您的时间将无法正确设置。
此答案的主要弱点是它仅适用于 Windows(它回答了提出的问题)。以后我会尝试发布一个跨平台的解决方案。
def isWindows() :
import platform
return platform.system() == 'Windows'
def getFileDateTimes( filePath ):
return ( os.path.getctime( filePath ),
os.path.getmtime( filePath ),
os.path.getatime( filePath ) )
def setFileDateTimes( filePath, datetimes ):
try :
import datetime
import time
if isWindows() :
import win32file, win32con
ctime = datetimes[0]
mtime = datetimes[1]
atime = datetimes[2]
# handle datetime.datetime parameters
if isinstance( ctime, datetime.datetime ) :
ctime = time.mktime( ctime.timetuple() )
if isinstance( mtime, datetime.datetime ) :
mtime = time.mktime( mtime.timetuple() )
if isinstance( atime, datetime.datetime ) :
atime = time.mktime( atime.timetuple() )
# adjust for day light savings
now = time.localtime()
ctime += 3600 * (now.tm_isdst - time.localtime(ctime).tm_isdst)
mtime += 3600 * (now.tm_isdst - time.localtime(mtime).tm_isdst)
atime += 3600 * (now.tm_isdst - time.localtime(atime).tm_isdst)
# change time stamps
winfile = win32file.CreateFile(
filePath, win32con.GENERIC_WRITE,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE,
None, win32con.OPEN_EXISTING,
win32con.FILE_ATTRIBUTE_NORMAL, None)
win32file.SetFileTime( winfile, ctime, atime, mtime )
winfile.close()
else : """MUST FIGURE OUT..."""
except : pass
【讨论】:
【参考方案8】:此代码适用于 python 3,无需
ValueError: astimezone() cannot be applied to a naive datetime
:
wintime = datetime.datetime.utcfromtimestamp(newtime).replace(tzinfo=datetime.timezone.utc)
winfile = win32file.CreateFile(
fname, win32con.GENERIC_WRITE,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE,
None, win32con.OPEN_EXISTING,
win32con.FILE_ATTRIBUTE_NORMAL, None)
win32file.SetFileTime(winfile, wintime)
winfile.close()
【讨论】:
使用 python 3 时出错:类型对象 'datetime.datetime' 没有属性 'datetime' @Vlad 使用不正确的导入语句是一个错误。该对象是我的示例中的 datetime.datetime,而不是您尝试使用它的 datetime.datetime.datetime。 你是对的 - 我已经更改了导入语句,但现在错误是a float is required
for datetime.datetime.utcfromtimestamp(newtime)
。在 python 3 中进行这项工作会很棒。【参考方案9】:
Yak shaving 赢得胜利。
import pywintypes, win32file, win32con
def changeFileCreationTime(fname, newtime):
wintime = pywintypes.Time(newtime)
winfile = win32file.CreateFile(
fname, win32con.GENERIC_WRITE,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE,
None, win32con.OPEN_EXISTING,
win32con.FILE_ATTRIBUTE_NORMAL, None)
win32file.SetFileTime(winfile, wintime, None, None)
winfile.close()
【讨论】:
如果您收到 ImportError 并想知道在哪里可以找到pywintypes
(就像我一样):sourceforge.net/projects/pywin32
@Delta 的解决方案要简单得多。
我喜欢这种“牦牛剃须”,确实这感觉就像我正在努力支持 Wintendo 操作系统。 :)
GENERIC_WRITE
请求此处不需要的数据访问权限,文件安全性可能未授予该权限,或者如果现有打开不共享写入数据访问权限,则可能导致共享冲突。该操作应该只请求FILE_WRITE_ATTRIBUTES
元数据访问,不需要数据访问共享,例如hfile = win32file.CreateFile(fname, ntsecuritycon.FILE_WRITE_ATTRIBUTES, 0, None, win32con.OPEN_EXISTING, 0, None)
.以上是关于如何更改 Windows 文件的文件创建日期?的主要内容,如果未能解决你的问题,请参考以下文章