自己主动操作文件中, 修改了文件内容, 导致文件最后修改时间被改变. 这并不是预期的结果.
我希望只有别人修改文件时,才导致文件修改时间变化. 这样我就不用计算文件的HASH值来判断文件是否被修改. 代之以简单的判断文件最后修改时间是否变化来决定文件是否被修改. 因为文件比较大的场景, 计算文件HASH的时间和文件大小成线性增长.
我想到的方法是自己操作文件之前保存文件原始时间 自己主动操作文件结束后, 恢复文件的原始时间。
当然,如果大家都这么搞,那就只有计算文件HASH,来判断文件是否被修改。
实现用到的WIN32API 为 ::GetFileTime 和 ::SetFileTime, 为了复用, 封装了CFileTimeOPT, 来进行简便的文件时间保存和恢复任务.
/**
* @file srcRestoreFileTimeAfterModify.cpp
* @brief 验证CFileTimeOPT在文件修改之前保存的文件时间,
* 是否能在文件被修改之后, 成功的恢复文件修改之前的文件时间
* 使文件除了验证HASH之外, 看起来和原来一样
*/
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <string>
#include "FileTimeOPT.h"
void WriteStuffToFile(CONST TCHAR * pcPathName);
void ShowFileTime(CFileTimeOPT * pFileTimeOPT,
CONST TCHAR * pcPathName, CONST TCHAR * pcTitle);
int _tmain(int argc, _TCHAR* argv[])
{
CFileTimeOPT FileTimeOPT;
CONST TCHAR * pcPathName = _T("c:\\test.txt"); /**< pcPathName must exist */
FileTimeOPT.SaveFileTime(pcPathName);
ShowFileTime(NULL, pcPathName,
_T("show file time before modify file"));
/** test: write stuff to file, to change file time */
WriteStuffToFile(pcPathName);
ShowFileTime(NULL, pcPathName, _T("show file time after modify file"));
FileTimeOPT.RestoreFileTime();
/** when file time restore, look the time is original time ? */
ShowFileTime(NULL, pcPathName,
_T("show file time after restore file time"));
/** run results
show file time before modify file
FileTimeOPT.GetStrLocalFileCreate() = 2011/11/06 12:39:19
FileTimeOPT.GetStrLocalFileWrite() = 2011/11/06 15:20:13 //original
FileTimeOPT.GetStrLocalFileAccess() = 2011/11/06 12:39:19
show file time after modify file
FileTimeOPT.GetStrLocalFileCreate() = 2011/11/06 12:39:19
FileTimeOPT.GetStrLocalFileWrite() = 2011/11/06 17:08:40 //new
FileTimeOPT.GetStrLocalFileAccess() = 2011/11/06 12:39:19
show file time after restore file time
FileTimeOPT.GetStrLocalFileCreate() = 2011/11/06 12:39:19
FileTimeOPT.GetStrLocalFileWrite() = 2011/11/06 15:20:13 //restore
FileTimeOPT.GetStrLocalFileAccess() = 2011/11/06 12:39:19
*/
getchar();
return 0;
}
void WriteStuffToFile(CONST TCHAR * pcPathName)
{
errno_t err;
FILE * hFile = NULL;
BYTE ucBuf[_MAX_PATH];
size_t nWrBack = 0;
ZeroMemory(ucBuf, _MAX_PATH);
_tcscpy_s((TCHAR *)ucBuf, sizeof(ucBuf) / sizeof(TCHAR),
_T("add content to file"));
err = _tfopen_s(&hFile, pcPathName, _T("a+b"));
if(hFile)
{
fwrite(ucBuf, sizeof(BYTE), _tcslen((TCHAR *)ucBuf), hFile);
fclose(hFile);
}
}
void ShowFileTime(CFileTimeOPT * pFileTimeOPT,
CONST TCHAR * pcPathName, CONST TCHAR * pcTitle)
{
DWORD dwRc = S_OK;
CFileTimeOPT FileTimeOPT;
if(!pFileTimeOPT)
{
pFileTimeOPT = &FileTimeOPT;
dwRc = pFileTimeOPT->SaveFileTime(pcPathName);
}
if(S_OK != dwRc)
{
_tprintf(_T("ERROR call FileTimeOPT.SaveFileTime\n"));
}
else
{
_tprintf(_T("%s\n"), pcTitle);
_tprintf(_T(" FileTimeOPT.GetStrLocalFileCreate() = %s\n")\
_T(" FileTimeOPT.GetStrLocalFileWrite() = %s\n")\
_T(" FileTimeOPT.GetStrLocalFileAccess() = %s\n\n"),
pFileTimeOPT->GetStrLocalFileCreate().c_str(),
pFileTimeOPT->GetStrLocalFileWrite().c_str(),
pFileTimeOPT->GetStrLocalFileAccess().c_str());
}
}
demo:
prjRestoreFileTimeAfterModify_V2011_1106_1652.rar