如何检索和更改 Windows 上文件的最后修改 time-stamp?
How to retrieve and change last modification time-stamp of a file on Windows?
我需要在 Windows 和 Linux 上实现相同的功能。
Linux部分是这样完成的:
#!/bin/sh
path_mainfunctions="../../data/scripts/mainfunctions.lua"
path_DisplayError="scripts/DisplayError.lua"
path_backup="scripts/mainfunctions.lua"
if [ -f $path_backup ]; then
# check if $path_mainfunctions is newer
alias stat='stat --format=%Y'
# retrieve Last-Modified Timestamp of mainfunctions.lua
lmt_mainfunctions=`stat $path_mainfunctions`
# retrieve Last-Modified Timestamp of backup file
lmt_backup=`stat $path_backup`
if [ $lmt_mainfunctions -gt $lmt_backup ]; then
# mainfunctions.lua is newer
# backup, append and touch
cp $path_mainfunctions $path_backup
cat $path_DisplayError >> $path_mainfunctions
touch $path_backup
fi
else
# backup
cp $path_mainfunctions $path_backup
# append DisplayError.lua to mainfunctions.lua
cat $path_DisplayError >> $path_mainfunctions
# touch $path_backup to make it newer than
# modified file $path_mainfunctions
touch $path_backup
fi
Windows 部分比较麻烦:
@ECHO off
SET path_mainfunctions="..\..\data\scripts\mainfunctions.lua"
SET path_DisplayError="scripts\DisplayError.lua"
SET path_backup="scripts\mainfunctions.lua"
@ECHO on
:: if it is the first time you install this mod
:: the mod should backup 'mainfunctions.lua'
:: automatically.
::
:: when the game is updated, the mod should
:: be able to detect such update:
:: - if %path_mainfunctions% is newer than
:: %path_backup%, the mod will install itself
::
:: - otherwise the mod will touch %path_backup%
IF EXIST %path_backup% (
:: check if %path_mainfunctions% is newer
ECHO f | XCOPY /d %path_mainfunctions% %path_backup%
:: TODO How to get last modified timestamp more easily?
:: SET DATE_MF=FORFILES %path_mainfunctions% /C "cmd /c ECHO @fdate"
:: SET DATE_BK=FORFILES %path_backup% /C "cmd /c ECHO @fdate"
::
:: TODO which date format will FORFILES command output?
:: - DD/MM/YYYY
:: - MM/DD/YYYY
:: - YYYY/MM/DD
::
:: split the string and do math to get timestamp
:: NOTE:
:: - SET /A RESULT = %VAR_A% * %VAR_B%
::
:: SET TIME_MF=FORFILES %path_mainfunctions% /C "cmd /c ECHO @ftime"
:: SET TIME_BK=FORFILES %path_backup% /C "cmd /c ECHO @ftime"
::
:: TODO compare last-modified time-stamp and do something
) ELSE (
:: Backup mainfunctions.lua
ECHO f | XCOPY %path_mainfunctions% %path_backup%
:: Append DisplayError.lua to mainfunctions.lua
TYPE %path_DisplayError% >> %path_mainfunctions%
:: touch %path_backup% to make it newer than
:: modified file %path_mainfunctions%
:: TODO how to touch a file in Windows ????
)
问题是我不知道如何检索和更改 Windows 上文件的最后修改 time-stamp,以防你忘记我的标题:)
如果你知道如何用VBScript解决问题,我想知道它是如何一步步实现的,谢谢:)
这里我将介绍一个纯批处理的解决方案。
Performing a touch is simple,虽然完全不直观。
copy /b "somepath\file.ext"+,, "somepath\file.ext" >nul
可以比较文件时间戳,但非常复杂。你可以use WMIC to get the last modified timestamp down to fractional seconds。时间戳的格式几乎使字符串比较几乎等同于时间顺序比较。问题是时间戳包括时区偏移量,表示为与 UTC (GMT) 的分钟差。因此,在从夏令时转换为标准时间期间,每年有一个小时简单的字符串比较会提供错误的答案。如果在计算机上更改了时区,您也可能得到错误的答案。可以补偿,但有一个更简单的解决方案:-)
Determining the newest file is simple if the files are all in the same folder。只需将数据文件(保留时间戳)复制到与更新文件相同的文件夹中。然后就可以用DIR命令按时间顺序列出文件,最后列出的就是最新的!
将它们放在一起,我得到:
@echo off
setlocal
:: Setup
set "dataPath=..\..\data\scripts"
set "updatePath=scripts"
set "data=mainfunctions.lua"
set "update=DisplayError.lua"
:: Make copy of original for use in date comparison and backup creation
copy /y "%dataPath%\%data%" "%updatePath%\%data%.compare" >nul
:: If this is the first install, then goto :update
if not exist "%updatePath%\%data%" goto update
:: List the update and compare files in chronological order
:: The last one listed will be the newest.
for /f "delims=" %%F in (
'dir /b /od "%updatePath%\%data%.compare" "%updatePath%\%update%"'
) do set "newest=%%F"
:: If newest equals update then goto :update
if "%newest%" equ "%update%" goto update
:: Nothing to do, so cleanup and exit
del "%updatePath%\%data%.compare"
exit /b
:update
:: Perform the update
type "%updatePath%\%update%" >> "%dataPath%\%data%"
:: Create the backup (also effectively "removes" the compare file)
move /y "%updatePath%\%data%.compare" "%updatePath%\%data%" >nul
:: "touch" the backup to give it a last-modified date greater than the update
copy /b "%updatePath%\%data%"+,, "%updatePath%\%data%" >nul
exit /b
我需要在 Windows 和 Linux 上实现相同的功能。
Linux部分是这样完成的:
#!/bin/sh
path_mainfunctions="../../data/scripts/mainfunctions.lua"
path_DisplayError="scripts/DisplayError.lua"
path_backup="scripts/mainfunctions.lua"
if [ -f $path_backup ]; then
# check if $path_mainfunctions is newer
alias stat='stat --format=%Y'
# retrieve Last-Modified Timestamp of mainfunctions.lua
lmt_mainfunctions=`stat $path_mainfunctions`
# retrieve Last-Modified Timestamp of backup file
lmt_backup=`stat $path_backup`
if [ $lmt_mainfunctions -gt $lmt_backup ]; then
# mainfunctions.lua is newer
# backup, append and touch
cp $path_mainfunctions $path_backup
cat $path_DisplayError >> $path_mainfunctions
touch $path_backup
fi
else
# backup
cp $path_mainfunctions $path_backup
# append DisplayError.lua to mainfunctions.lua
cat $path_DisplayError >> $path_mainfunctions
# touch $path_backup to make it newer than
# modified file $path_mainfunctions
touch $path_backup
fi
Windows 部分比较麻烦:
@ECHO off
SET path_mainfunctions="..\..\data\scripts\mainfunctions.lua"
SET path_DisplayError="scripts\DisplayError.lua"
SET path_backup="scripts\mainfunctions.lua"
@ECHO on
:: if it is the first time you install this mod
:: the mod should backup 'mainfunctions.lua'
:: automatically.
::
:: when the game is updated, the mod should
:: be able to detect such update:
:: - if %path_mainfunctions% is newer than
:: %path_backup%, the mod will install itself
::
:: - otherwise the mod will touch %path_backup%
IF EXIST %path_backup% (
:: check if %path_mainfunctions% is newer
ECHO f | XCOPY /d %path_mainfunctions% %path_backup%
:: TODO How to get last modified timestamp more easily?
:: SET DATE_MF=FORFILES %path_mainfunctions% /C "cmd /c ECHO @fdate"
:: SET DATE_BK=FORFILES %path_backup% /C "cmd /c ECHO @fdate"
::
:: TODO which date format will FORFILES command output?
:: - DD/MM/YYYY
:: - MM/DD/YYYY
:: - YYYY/MM/DD
::
:: split the string and do math to get timestamp
:: NOTE:
:: - SET /A RESULT = %VAR_A% * %VAR_B%
::
:: SET TIME_MF=FORFILES %path_mainfunctions% /C "cmd /c ECHO @ftime"
:: SET TIME_BK=FORFILES %path_backup% /C "cmd /c ECHO @ftime"
::
:: TODO compare last-modified time-stamp and do something
) ELSE (
:: Backup mainfunctions.lua
ECHO f | XCOPY %path_mainfunctions% %path_backup%
:: Append DisplayError.lua to mainfunctions.lua
TYPE %path_DisplayError% >> %path_mainfunctions%
:: touch %path_backup% to make it newer than
:: modified file %path_mainfunctions%
:: TODO how to touch a file in Windows ????
)
问题是我不知道如何检索和更改 Windows 上文件的最后修改 time-stamp,以防你忘记我的标题:)
如果你知道如何用VBScript解决问题,我想知道它是如何一步步实现的,谢谢:)
这里我将介绍一个纯批处理的解决方案。
Performing a touch is simple,虽然完全不直观。
copy /b "somepath\file.ext"+,, "somepath\file.ext" >nul
可以比较文件时间戳,但非常复杂。你可以use WMIC to get the last modified timestamp down to fractional seconds。时间戳的格式几乎使字符串比较几乎等同于时间顺序比较。问题是时间戳包括时区偏移量,表示为与 UTC (GMT) 的分钟差。因此,在从夏令时转换为标准时间期间,每年有一个小时简单的字符串比较会提供错误的答案。如果在计算机上更改了时区,您也可能得到错误的答案。可以补偿,但有一个更简单的解决方案:-)
Determining the newest file is simple if the files are all in the same folder。只需将数据文件(保留时间戳)复制到与更新文件相同的文件夹中。然后就可以用DIR命令按时间顺序列出文件,最后列出的就是最新的!
将它们放在一起,我得到:
@echo off
setlocal
:: Setup
set "dataPath=..\..\data\scripts"
set "updatePath=scripts"
set "data=mainfunctions.lua"
set "update=DisplayError.lua"
:: Make copy of original for use in date comparison and backup creation
copy /y "%dataPath%\%data%" "%updatePath%\%data%.compare" >nul
:: If this is the first install, then goto :update
if not exist "%updatePath%\%data%" goto update
:: List the update and compare files in chronological order
:: The last one listed will be the newest.
for /f "delims=" %%F in (
'dir /b /od "%updatePath%\%data%.compare" "%updatePath%\%update%"'
) do set "newest=%%F"
:: If newest equals update then goto :update
if "%newest%" equ "%update%" goto update
:: Nothing to do, so cleanup and exit
del "%updatePath%\%data%.compare"
exit /b
:update
:: Perform the update
type "%updatePath%\%update%" >> "%dataPath%\%data%"
:: Create the backup (also effectively "removes" the compare file)
move /y "%updatePath%\%data%.compare" "%updatePath%\%data%" >nul
:: "touch" the backup to give it a last-modified date greater than the update
copy /b "%updatePath%\%data%"+,, "%updatePath%\%data%" >nul
exit /b