• C++ 设置文件最近修改时间


    利用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
    ", 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.
    ");
                        }
                        else
                        {
                            printf("reset time fail.error=%d
    ", 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;
    }
  • 相关阅读:
    AOP从静态代理到动态代理 Emit实现
    Emit基础入门 系列文章
    ContextAttribute与ContextBoundObject应用的探究
    吞云吐烦忧
    动态编译代码框架发布CZGL.Roslyn
    AutoMapper 入门
    Attribute在.net编程中的应用
    C#反射与特性 系列文章
    静态代理和动态代理方式分别实现AOP拦截功能
    内网安全攻防:渗透测试指南——第8章 权限维持分析及防御
  • 原文地址:https://www.cnblogs.com/tangxin-blog/p/7290438.html
Copyright © 2020-2023  润新知