1. 程式人生 > >C++ 設置文件最近修改時間

C++ 設置文件最近修改時間

err 目錄 window .cpp directory spa reat tor att

利用VS開發C++項目,經常發現修改系統時間後,每次編譯過程會變得很慢,其原因就是當你把系統時間調到未來的一個時間點,然後有意或者無意編輯過一些代碼文件,那麽這些文件的時間戳就停留在未來.

當你把系統時間調到現在後,編譯器每次編譯的時候,總會判定這些文件是最新的,所以總是會把這些文件編譯一遍,如果這些文件中有某些被其他文件引用,那麽會有更多的文件被重新編譯,而且這種過程每次

編譯都會執行一遍,導致編譯速度降低.為了解決這個問題,我特意寫了一個小工具.

這個工具的原理跟簡單,找出指定目錄下時間戳大於當前時間的文件,並把它們的時間戳設置為現在時間.

調用的時候,配合一個bat腳本,把需要檢查的代碼目錄傳進去就好了,例如

echo off
ResetFileTime MsgDefine Server
pause

#include <io.h>
#include <windows.h>
#include <stdint.h>
#include <vector>
#include <string>
#include <set>
#include <stdio.h>
#include <iostream>

bool IsCompileFile(const std::string & extension)
{
    
static std::set<std::string> setComplieFileExtension = {".cpp", ".c", ".cc", ".h", ".hpp"}; return setComplieFileExtension.find(extension) != setComplieFileExtension.end(); } std::string GetFileNameExtension(const std::string & fileName) { /* DWORD dwAttrib = GetFileAttributes(fileName.c_str()); if (dwAttrib == INVALID_FILE_ATTRIBUTES) { return ""; } if (dwAttrib & FILE_ATTRIBUTE_DIRECTORY) { return ""; }
*/ size_t dotpos = fileName.find_last_of("."); if(dotpos == std::string::npos) { return fileName; } return fileName.substr(dotpos, fileName.length() - dotpos); } bool CompareSystemTime(const SYSTEMTIME & lhs, const SYSTEMTIME & rhs) { if(lhs.wYear > rhs.wYear) { return true; } else if(lhs.wYear == rhs.wYear && lhs.wMonth > rhs.wMonth) { return true; } else if(lhs.wYear == rhs.wYear && lhs.wMonth == rhs.wMonth && lhs.wDay > rhs.wDay) { return true; } else if(lhs.wYear == rhs.wYear && lhs.wMonth == rhs.wMonth && lhs.wDay == rhs.wDay && lhs.wHour > rhs.wHour) { return true; } else if(lhs.wYear == rhs.wYear && lhs.wMonth == rhs.wMonth && lhs.wDay == rhs.wDay && lhs.wHour == rhs.wHour && lhs.wMinute > rhs.wMinute) { return true; } else if(lhs.wYear == rhs.wYear && lhs.wMonth == rhs.wMonth && lhs.wDay == rhs.wDay && lhs.wHour == rhs.wHour && lhs.wMinute == rhs.wMinute && lhs.wSecond > rhs.wSecond) { return true; } else if(lhs.wYear == rhs.wYear && lhs.wMonth == rhs.wMonth && lhs.wDay == rhs.wDay && lhs.wHour == rhs.wHour && lhs.wMinute == rhs.wMinute && lhs.wSecond == rhs.wSecond && lhs.wMilliseconds > rhs.wMilliseconds) { return true; } return false; } void DumpSystemTime(const std::string & prefix, const SYSTEMTIME & t) { printf("%s %04d-%02d-%02d %02d:%02d:%02d\n", prefix.c_str(), t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond); } void ResetFileTime(const std::string & dir) { WIN32_FIND_DATA fileInfo; HANDLE hFile = nullptr; char tmpPath[MAX_PATH] = { 0 }; sprintf_s(tmpPath, "%s\\*.*", dir.c_str()); if((hFile = FindFirstFile(tmpPath, &fileInfo)) == HANDLE(-1)) { return; } do { if(fileInfo.dwFileAttributes & _A_SUBDIR) { if(strcmp(fileInfo.cFileName, ".") == 0 || strcmp(fileInfo.cFileName, "..") == 0) { continue; } sprintf_s(tmpPath, "%s\\%s", dir.c_str(), fileInfo.cFileName); ResetFileTime(tmpPath); } else { sprintf_s(tmpPath, "%s\\%s", dir.c_str(), fileInfo.cFileName); std::string extension = GetFileNameExtension(fileInfo.cFileName); if(IsCompileFile(extension)) { FILETIME lastWriteLocalFileTime; FileTimeToLocalFileTime(&fileInfo.ftLastWriteTime, &lastWriteLocalFileTime); SYSTEMTIME lastWriteLocalSysTime, nowTime; FileTimeToSystemTime(&lastWriteLocalFileTime, &lastWriteLocalSysTime); GetLocalTime(&nowTime); if(CompareSystemTime(lastWriteLocalSysTime, nowTime)) { HANDLE file = ::CreateFile(tmpPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL); DumpSystemTime(fileInfo.cFileName, lastWriteLocalSysTime); FILETIME nowWriteLocalFileTime; SystemTimeToFileTime(&nowTime, &nowWriteLocalFileTime); FILETIME nowWriteSysFileTime; LocalFileTimeToFileTime(&nowWriteLocalFileTime, &nowWriteSysFileTime); BOOL ret = SetFileTime(file, &nowWriteSysFileTime, &nowWriteSysFileTime, &nowWriteSysFileTime); if(ret == TRUE) { printf("reset time succ.\n"); } else { printf("reset time fail.error=%d\n", GetLastError()); } } } } } while(FindNextFile(hFile, &fileInfo) == TRUE); FindClose(hFile); } int32_t main(int32_t argc, char *argv[]) { for(int32_t i = 1; i < argc; ++i) { std::string dir = argv[i]; ResetFileTime(dir); } return 0; }

C++ 設置文件最近修改時間