Python 如何更改 Windows 文件的文件创建日期?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4996405/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 18:33:23  来源:igfitidea点击:

How do I change the file creation date of a Windows file?

pythonwindowsfiledatetime

提问by Claudiu

How do I change the file creation date of a Windows file from Python?

如何从 Python 更改 Windows 文件的文件创建日期?

采纳答案by Claudiu

Yak shavingfor the win.

牦牛剃毛取胜。

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()

回答by Delta

import os
os.utime(path, (accessed_time, modified_time))

http://docs.python.org/library/os.html

http://docs.python.org/library/os.html

At least it changes the modification time, without using win32 module.

至少它改变了修改时间,不使用win32模块。

回答by panda-34

This code works on python 3 without ValueError: astimezone() cannot be applied to a naive datetime:

此代码适用于 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()

回答by BuvinJ

Here's a more robust version of the accepted answer. It also has the opposing getter function. This addresses created, modified, and accessed datetimes. It handles having the datetimes parameters provided as either datetime.datetime objects, or as "seconds since the epoch" (what the getter returns). Further, it adjusts for Day Light Saving time, which the accepted answer does not. Without that, your times will not be set correctly when you set a winter or summer time during the opposing phase of your actual system time.

这是已接受答案的更强大版本。它还具有相反的吸气功能。这将解决创建、修改和访问的日期时间。它处理将 datetimes 参数提供为 datetime.datetime 对象或“自纪元以来的秒数”(getter 返回的内容)。此外,它会针对夏令时进行调整,而接受的答案并未对此进行调整。否则,当您在实际系统时间的相反阶段设置冬季或夏季时间时,您的时间将无法正确设置。

The major weakness of this answer is that it is for Windows only (which answers the question posed). In the future, I'll try to post a cross platform solution.

这个答案的主要弱点是它仅适用于 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    

回答by percy507

install pywin32 extension firsthttps://sourceforge.net/projects/pywin32/files/pywin32/Build%20221/

首先安装 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)

回答by Kardo Paska

Here is a solution that works on Python 3.5 and windows 7. Very easy. I admit it's sloppy coding... but it works. You're welcome to clean it up. I just needed a quick soln.

这是一个适用于 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 )

回答by Delgan

I did not want to bring the whole pywin32/ win32filelibrary solely to set the creation time of a file, so I made the win32-setctimepackage which does just that.

我不想单独使用整个pywin32/win32file库来设置文件的创建时间,所以我制作了一个win32-setctime包来做到这一点。

pip install win32-setctime

And then use it like that:

然后像这样使用它:

from win32_setctime import setctime

setctime("my_file.txt", 1561675987.509)


Basically, the function can be reduced to just a few lines without needing any dependency other that the built-in ctypesPython library:

基本上,该函数可以减少到只有几行,而无需除了内置ctypesPython 库之外的任何依赖项:

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)

For advanced management (like error handling), see the source code of win32_setctime.py.

对于先进的管理(如错误处理),看到的源代码win32_setctime.py