当前位置: 首页 > news >正文

网站改用绝对地址的好处疫情放开最新消息今天

网站改用绝对地址的好处,疫情放开最新消息今天,沈总网站建设,电商运营 网站运营简单实现日志保存, 支持设置日志文件数量, 单个日志文件大小上限, 自动超时保存日志, 日志缓存超限保存 CLogUtils.h #pragma once#include <string> #include <windows.h> #include <vector> #include <map> #include <mutex> #include <tc…

简单实现日志保存, 支持设置日志文件数量, 单个日志文件大小上限, 自动超时保存日志, 日志缓存超限保存

CLogUtils.h

#pragma once#include <string>
#include <windows.h>
#include <vector>
#include <map>
#include <mutex>
#include <tchar.h>
#include <thread>#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endifnamespace CLogUtils
{#define USR_STRING_BUFFER_CONTENT       (1)                 //使用字符串作为日志缓冲
#define HISTORY_FILE_MAX_COUNT          (16)                //最多日志文件历史数量
#define AUTO_SAVE_TIME_OUT              (1000 * 60)         //自动保存超时时间(毫秒)
#define LOG_FILE_MAX_SIZE               (1024 * 1024 * 64)  //单个日志文件大小阈值(字节)
#define LOG_BUF_MAX_COUNT               (512)               //日志缓冲大小阈值#define LOG_INFO(format, ...)\global_logger.Logging(_T(" INFO"), _T(__FILE__), _T(__FUNCTION__), __LINE__, format, ##__VA_ARGS__);#define LOG_DEBUG(format, ...)\global_logger.Logging(_T("DEBUG"), _T(__FILE__), _T(__FUNCTION__), __LINE__, format, ##__VA_ARGS__);#define LOG_WARN(format, ...)\global_logger.Logging(_T(" WARN"), _T(__FILE__), _T(__FUNCTION__), __LINE__, format, ##__VA_ARGS__);#define LOG_ERROR(format, ...)\global_logger.Logging(_T("ERROR"), _T(__FILE__), _T(__FUNCTION__), __LINE__, format, ##__VA_ARGS__);class CLogHelper{public:#define LogInfo(format, ...)\Logging(_T(" INFO"), _T(__FILE__), _T(__FUNCTION__), __LINE__, format, ##__VA_ARGS__);#define LogDebug(format, ...)\Logging(_T("DEBUG"), _T(__FILE__), _T(__FUNCTION__), __LINE__, format, ##__VA_ARGS__);#define LogWarn(format, ...)\Logging(_T(" WARN"), _T(__FILE__), _T(__FUNCTION__), __LINE__, format, ##__VA_ARGS__);#define LogError(format, ...)\Logging(_T("ERROR"), _T(__FILE__), _T(__FUNCTION__), __LINE__, format, ##__VA_ARGS__);public://// @brief: 构造// @param: nFileSize        文件大小阈值(字节)// @param: nTmpCount        缓存条目阈值// @param: nIntervalTime    自动存储时间间隔(毫秒)// @ret: voidCLogHelper(const _tstring& strDir = _T(""),const _tstring& strName = _T(""),DWORD nFileSize = LOG_FILE_MAX_SIZE,DWORD nTmpCount = LOG_BUF_MAX_COUNT,DWORD nIntervalTime = AUTO_SAVE_TIME_OUT);//删除拷贝构造与赋值重载CLogHelper(const CLogHelper&) = delete;CLogHelper& operator = (const CLogHelper&) = delete;~CLogHelper();//// @brief: 记录一条日志// @param: pstrLevel    日志等级// @param: pstrFile     源码文件// @param: pstrFunc     源码函数// @param: nLine        行数// @param: pstrFormat   格式化字符串// @param: ...          可变参数// @ret: voidvoid Logging(LPCTSTR pstrLevel,LPCTSTR pstrFile,LPCTSTR pstrFunc,UINT nLine,LPCTSTR pstrFormat,...);//// @brief: 清空已经存储的日志文件// @ret: voidvoid Clear();//// @brief: 格式化字符串// @param: void// @ret: bool 执行结果_tstring Format(LPCTSTR pstrFormat, ...);//// @brief: 获取目录下文件路径// @ret: std::vector<_tstring> 日志文件列表std::map<int64_t, _tstring> GetLogFileList(const _tstring& strDir);// // @brief: 获取当前进程完全路径// @ret: 当前进程完全路径 如 D:\Software\HxDPortableSetup.exestatic _tstring GetCurrentModulePath();// // @brief: 获取当前进程所在目录// @ret: 当前进程所在目录 如 D:\Softwarestatic _tstring GetCurrentModuleDir();// // @brief: 获取当前进程名// @ret: 当前进程名 如 HxDPortableSetup.exestatic _tstring GetCurrentModuleName(bool bHasExt = false);// // @brief: 获取文件所在文件夹// @param: strPath     文件名, 如: D:\Software\HxDPortableSetup.exe// @ret: 文件夹        如 D:\Softwarestatic _tstring GetFileDir(const _tstring& strPath);// // @brief: 获取文件名// @param: strPath     文件名, 如: D:\Software\HxDPortableSetup.exe// @param: bHasExt     是否包含扩展名// @ret: 文件夹        如 HxDPortableSetupstatic _tstring GetFileName(const _tstring& strPath, bool bHasExt = false);// // @brief: 检查文件是否存在// @param: strPath     文件名, 如: D:\Software\HxDPortableSetup.exe// @ret: 是否存在      存在返回 truestatic bool IsArchive(const _tstring& strPath);// // @brief: 检查文件是否存在// @param: strPath     文件名, 如: D:\Software\HxDPortableSetup.exe// @ret: 是否存在      存在返回 truestatic bool IsDirectory(const _tstring& strPath);//// @brief: 创建目录(递归)// @param: strPath      路径// @ret: 成功返回truestatic bool CreateDir(const _tstring& strPath);//// @brief: 删除文件// @param: strPath      路径// @ret: 成功返回truestatic bool DeleteArchive(const _tstring& strPath);//// @brief: 获取当前时间戳字符串// @param: void// @ret: _tstring 时间戳字符串          如: 2023-10-11 17:43:00.617static _tstring GetCurrentTimeString();//// @brief: 获取当前日期字符串// @param: void// @ret: _tstring 时间戳字符串          如: 2023-10-11static _tstring GetCurrentDateString();//// @brief: 获取当前时间戳// @param: void// @ret: 时间戳(单位: 毫秒)    如: 1697017380617static int64_t GetCurrentTimestamp();//// @brief: 时间戳转字符串  // @param: strFormat    格式化字符串 如: "%04d-%02d-%02d %02d:%02d:%02d.%d"// @param: timestamp    时间戳 如: 1697017380617// @ret: 时间字符串            如: 2023-10-11 17:43:00.617static _tstring TimestampToString(const _tstring& strFormat = _T("%04d-%02d-%02d %02d:%02d:%02d.%d"), int64_t timestamp = 0);//// @brief: 获取文件大小// @param: strPath      路径// @ret: 文件大小unsigned long long GetFileSize(const _tstring& strPath);private://// @brief: 调整日志文件数量// @param: void// @ret: voidvoid AdjustLogFile();//// @brief: 初始化// @param: void// @ret: bool 执行结果bool Initialize();//// @brief: 取消初始化// @param: void// @ret: voidvoid Uninitialize();//// @brief: 初始化日志文件// @param: void// @ret: int 日志文件索引void InitLogFile();//// @brief: 生成日志转储文件路径// @param: void// @ret: voidvoid GenerateLogFilePath();//// @brief: 输出日志到文件// @ret: bool 执行结果bool OutputToFile();private:LPTSTR m_lpBuf = nullptr;                   //格式化字符串使用的缓冲指针std::mutex  m_Lock;                         //线程安全锁std::vector<_tstring> m_logList;            //日志记录std::map<int64_t, _tstring> m_logFileList;  //日志文件记录, 按照时间戳排序std::thread m_threadAutoSave;               //自动保存线程对象HANDLE m_hEvent = nullptr;                  //通知事件, 使用自动转储的超时等待HANDLE m_hFile = INVALID_HANDLE_VALUE;      //文件句柄, 日志文件写入使用int64_t  m_nFileTimetamp = 0;               //日志文件时间戳_tstring m_strSaveDir;                      //日志存放目录_tstring m_strSaveName;                     //日志文件名_tstring m_strFilePath;                     //当前日志文件路径bool m_bStop = false;                       //停止标记bool m_bFirst = false;                      //首次记录日志标记_tstring m_strLogContent;                   //日志内容DWORD m_MaxFileSize = 0;                    //文件大小阈值(到达阈值则转储到文件)DWORD m_MaxTempCount = 0;                   //缓存条目阈值(到达阈值则转储到文件)DWORD m_AutoSaveTime = 0;                   //自动保存间隔时间阈值(到达阈值则转储到文件)DWORD m_LogTotalSize = 0;                   //日志文件统计DWORD m_NextItemSize = 0;                   //下一条目日志大小DWORD m_LogItemCount = 0;                   //日志缓冲统计};extern CLogHelper global_logger;                //全局静态实例
}

CLogUtils.cpp

#include "CLogUtils.h"
#include <strsafe.h>
#include <tchar.h>namespace CLogUtils
{#define FORMAT_BUFFER_CH_SIZE           (1024 * 4)       //字符串格式化字符缓冲大小(字符)//全局实例构造CLogHelper global_logger(_T(""), CLogHelper::GetCurrentModuleName(true) + _T("_global"), LOG_FILE_MAX_SIZE, LOG_BUF_MAX_COUNT, AUTO_SAVE_TIME_OUT);CLogHelper::CLogHelper(const _tstring& strDir/* = _T("")*/,const _tstring& strName/* = _T("")*/,DWORD nFileSize/* = 1024 * 1024*/,DWORD nTmpCount/* = 100*/,DWORD nIntervalTime/* = 60*/) : m_strSaveDir(strDir),m_strSaveName(strName),m_MaxFileSize(nFileSize), m_MaxTempCount(nTmpCount), m_AutoSaveTime(nIntervalTime){if (m_MaxFileSize < LOG_FILE_MAX_SIZE){m_MaxFileSize = LOG_FILE_MAX_SIZE;}if (m_AutoSaveTime < AUTO_SAVE_TIME_OUT){m_AutoSaveTime = AUTO_SAVE_TIME_OUT;}//默认目录为当前进程目录if (m_strSaveDir.empty()){m_strSaveDir = GetCurrentModuleDir();}//默认文件名为当前进程名if (m_strSaveName.empty()){m_strSaveName = GetCurrentModuleName(true);}//目录不存在就创建目录if (!IsDirectory(m_strSaveDir)){CreateDir(m_strSaveDir);}this->Initialize();}CLogHelper::~CLogHelper(){this->Uninitialize();}bool CLogHelper::Initialize(){if (nullptr == m_lpBuf){m_lpBuf = (LPTSTR)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, FORMAT_BUFFER_CH_SIZE * sizeof(TCHAR));}if (nullptr == m_hEvent){m_hEvent = ::CreateEvent(nullptr, false, false, nullptr);}//开启一个线程进行自动保存m_threadAutoSave = std::move(std::thread([this](){//超时或者退出时转储日志到文件while (!m_bStop){DWORD dwWait = ::WaitForSingleObject(m_hEvent, m_AutoSaveTime);switch (dwWait){case WAIT_TIMEOUT:case WAIT_OBJECT_0:{std::lock_guard<std::mutex> lock(m_Lock);this->OutputToFile();m_logList.clear();}break;default:break;}}}));return nullptr != m_lpBuf;}void CLogHelper::Uninitialize(){if (nullptr != m_lpBuf){::HeapFree(::GetProcessHeap(), 0, m_lpBuf);m_lpBuf = nullptr;}if (nullptr != m_hEvent){m_bStop = true;::SetEvent(m_hEvent);}if (m_threadAutoSave.joinable()){m_threadAutoSave.join();}if (INVALID_HANDLE_VALUE != m_hFile){::CloseHandle(m_hFile);m_hFile = INVALID_HANDLE_VALUE;}}bool CLogHelper::OutputToFile(){DWORD dwNumberOfBytesWrite = 0;bool bSuccess = false;if (INVALID_HANDLE_VALUE == m_hFile){return false;}#if USR_STRING_BUFFER_CONTENT//没有需要写入的日志if (m_strLogContent.empty()){return true;}bSuccess = ::WriteFile(m_hFile, m_strLogContent.c_str(), (DWORD)(m_strLogContent.size() * sizeof(TCHAR)), &dwNumberOfBytesWrite, NULL);m_strLogContent.clear();
#else//没有需要写入的日志if (m_logList.empty()){return true;}for (const auto& item : m_logList){bSuccess = ::WriteFile(m_hFile, item.c_str(), (DWORD)(item.size() * sizeof(TCHAR)), &dwNumberOfBytesWrite, NULL);if (!bSuccess){break;}}#endifreturn bSuccess;}void CLogHelper::Logging(LPCTSTR pstrLevel,LPCTSTR pstrFile,LPCTSTR pstrFunc,UINT nLine,LPCTSTR pstrFormat,...){if (nullptr == m_lpBuf){return;}TCHAR szBuf[MAX_PATH] = { 0 };DWORD dwTid = ::GetCurrentThreadId();_tstring strLogContent;//日志格式前缀 [时间] [等级] [十六进制线程ID(十进制线程ID)] [源码位置 : 行数] [函数名]::StringCchPrintf(szBuf, _countof(szBuf), _T("[%s] [%s] [%0.8X(%d)] [%s : %d] [%s] "),GetCurrentTimeString().c_str(),pstrLevel,dwTid,dwTid,pstrFile,nLine,pstrFunc);strLogContent = szBuf;//格式化日志内容if (nullptr != m_lpBuf){int nSize = 0;va_list args;va_start(args, pstrFormat);nSize = _vsntprintf_s(m_lpBuf, FORMAT_BUFFER_CH_SIZE, _TRUNCATE, pstrFormat, args);va_end(args);}//获取单行日志内容 + 固定前缀内容 + 真实内容strLogContent += m_lpBuf;strLogContent += _T("\r\n");m_NextItemSize = (DWORD)(strLogContent.size() * sizeof(TCHAR));std::lock_guard<std::mutex> lock(m_Lock);//首次启动时, 重置大小统计if (!m_bFirst){InitLogFile();AdjustLogFile();m_LogTotalSize = (DWORD)GetFileSize(m_strFilePath);m_bFirst = true;}//单个日志文件大小即将达到或超过阈值则输出到文件, 启用新的文件存储if ((m_LogTotalSize + m_NextItemSize) >= m_MaxFileSize){OutputToFile();m_logList.clear();::CloseHandle(m_hFile);m_hFile = INVALID_HANDLE_VALUE;(void)GenerateLogFilePath();m_LogTotalSize = (DWORD)GetFileSize(m_strFilePath);AdjustLogFile();}//已缓存条目达到阈值则输出到文件
#if USR_STRING_BUFFER_CONTENTelse if (m_LogItemCount >= m_MaxTempCount){OutputToFile();m_strLogContent.clear();m_LogItemCount = 0;}
#elseelse if (m_logList.size() >= m_MaxTempCount){OutputToFile();m_logList.clear();}#endif#if USR_STRING_BUFFER_CONTENTm_strLogContent += strLogContent;m_LogItemCount++;
#elsem_logList.emplace_back(strLogContent);
#endif//累加统计单个日志文件大小m_LogTotalSize += m_NextItemSize;return;}void CLogHelper::Clear(){std::lock_guard<std::mutex> lock(m_Lock);if (INVALID_HANDLE_VALUE != m_hFile){::CloseHandle(m_hFile);m_hFile = INVALID_HANDLE_VALUE;}m_logFileList = GetLogFileList(m_strSaveDir);for (const auto& item: m_logFileList){DeleteArchive(item.second);}m_logFileList.clear();}void CLogHelper::AdjustLogFile(){//检查文件数量是否到达阈值, 到达的话删除前面的文件if (m_logFileList.size() > HISTORY_FILE_MAX_COUNT){size_t nDeleteCount = m_logFileList.size() - HISTORY_FILE_MAX_COUNT;size_t nIndex = 0;//删除多出的文件for (const auto& item : m_logFileList){DeleteArchive(item.second);nIndex++;if (nIndex >= nDeleteCount){break;}}//文件名整体向前移动_tstring lastPath;for (const auto& item : m_logFileList){if (lastPath.empty()){::MoveFileEx(item.second.c_str(), lastPath.c_str(), MOVEFILE_DELAY_UNTIL_REBOOT);}lastPath = item.second;}//从日志文件记录列表中删除for (size_t i = 0; i < nDeleteCount; i++){m_logFileList.erase(m_logFileList.begin());}}}void CLogHelper::InitLogFile(){//如果上次最后一个日志文件大小还能存储日志, 就沿用上次的日志文件m_logFileList = GetLogFileList(m_strSaveDir);if (!m_logFileList.empty()){auto itLast = m_logFileList.end();itLast--;m_nFileTimetamp = itLast->first;m_strFilePath = itLast->second;//上次最后一个日志文件不能存储更多日志, 则生成新的日志文件路径unsigned long long ullFileSize = (DWORD)GetFileSize(m_strFilePath);if ((ullFileSize + m_NextItemSize) >= m_MaxFileSize){(void)GenerateLogFilePath();}else{//打开文件以续写日志m_hFile = CreateFile(m_strFilePath.c_str(),GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);//在文件末尾追加内容LARGE_INTEGER  liDistanceToMove = { 0 };::SetFilePointerEx(m_hFile, liDistanceToMove, NULL, FILE_END);}}else{(void)GenerateLogFilePath();}}void CLogHelper::GenerateLogFilePath(){//得到日志文件时间戳m_nFileTimetamp = GetCurrentTimestamp();//得到日志文件路径m_strFilePath = Format(_T("%s\\%s_%s.log"),m_strSaveDir.c_str(),m_strSaveName.c_str(),TimestampToString(_T("%04d-%02d-%02d_%02d-%02d-%02d-%03d"),m_nFileTimetamp).c_str());//创建一下文件(防止在资源管理器中看不到新的日志文件)m_hFile = CreateFile(m_strFilePath.c_str(),GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);//在文件末尾追加内容LARGE_INTEGER  liDistanceToMove = { 0 };::SetFilePointerEx(m_hFile, liDistanceToMove, NULL, FILE_END);m_logFileList.insert(std::make_pair(m_nFileTimetamp, m_strFilePath));}std::map<int64_t, _tstring> CLogHelper::GetLogFileList(const _tstring& strDir){std::map<int64_t, _tstring> fileList;WIN32_FIND_DATA findData = { 0 };HANDLE hFindHandle = INVALID_HANDLE_VALUE;hFindHandle = FindFirstFile((strDir + _T("\\*.*")).c_str(), &findData);if (INVALID_HANDLE_VALUE == hFindHandle){return fileList;}do{_tstring strName = findData.cFileName;//非目录if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){//检查输入规则int nConverted = 0;SYSTEMTIME st = { 0 };_tstring strPath = strDir + _T("\\") + strName;_tstring strPrefix = Format(_T("%s_%%4hd-%%2hd-%%2hd_%%2hd-%%2hd-%%2hd-%%3hd.log"), m_strSaveName.c_str());nConverted = _stscanf_s(findData.cFileName, strPrefix.c_str(),&st.wYear, &st.wMonth, &st.wDay, &st.wHour,&st.wMinute, &st.wSecond, &st.wMilliseconds);//检查文件名规则是否符合要求if (7 == nConverted){FILETIME ftFile = { 0 };FILETIME ftLocal = { 0 };int64_t timestamp = 0;::SystemTimeToFileTime(&st, &ftLocal);::LocalFileTimeToFileTime(&ftLocal, &ftFile);timestamp = ((int64_t)ftFile.dwHighDateTime << 32) | ftFile.dwLowDateTime;timestamp = (timestamp - 116444736000000000) / 10000;fileList.insert(std::make_pair(timestamp, strPath));}}//上一级目录与当前目录跳过if (0 == _tcscmp(findData.cFileName, _T(".")) || 0 == _tcscmp(findData.cFileName, _T(".."))){continue;}} while (::FindNextFile(hFindHandle, &findData));::FindClose(hFindHandle);return fileList;}_tstring CLogHelper::Format(LPCTSTR pstrFormat, ...){_tstring strResult;if (nullptr != m_lpBuf){int nSize = 0;va_list args;va_start(args, pstrFormat);nSize = _vsntprintf_s(m_lpBuf, FORMAT_BUFFER_CH_SIZE, _TRUNCATE, pstrFormat, args);va_end(args);strResult = m_lpBuf;}return strResult;}_tstring CLogHelper::GetCurrentTimeString(){TCHAR szBuf[MAX_PATH] = { 0 };SYSTEMTIME st = { 0 };(void)::GetLocalTime(&st);::StringCchPrintf(szBuf, _countof(szBuf),_T("%04d-%02d-%02d %02d:%02d:%02d.%d"),st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);return szBuf;}_tstring CLogHelper::GetCurrentDateString(){TCHAR szBuf[MAX_PATH] = { 0 };SYSTEMTIME st = { 0 };(void)::GetLocalTime(&st);::StringCchPrintf(szBuf, _countof(szBuf), _T("%04d-%02d-%02d"), st.wYear, st.wMonth, st.wDay);return szBuf;}int64_t CLogHelper::GetCurrentTimestamp(){int64_t timeStamp = 0;(void)::GetSystemTimeAsFileTime((FILETIME*)&timeStamp);return (timeStamp - 116444736000000000) / 10000;}_tstring CLogHelper::TimestampToString(const _tstring& strFormat, int64_t timestamp){TCHAR szBuf[MAX_PATH] = { 0 };SYSTEMTIME st = { 0 };FILETIME ftFile = { 0 };FILETIME ftLocal = { 0 };timestamp = timestamp * 10000 + 116444736000000000;ftFile.dwLowDateTime = timestamp & 0xFFFFFFFF;ftFile.dwHighDateTime = timestamp >> 32;::FileTimeToLocalFileTime(&ftFile, &ftLocal);::FileTimeToSystemTime(&ftLocal, &st);::StringCchPrintf(szBuf, _countof(szBuf),strFormat.c_str(),st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);return szBuf;}_tstring CLogHelper::GetCurrentModulePath(){TCHAR szCurPath[MAX_PATH] = { 0 };::GetModuleFileName(NULL, szCurPath, _countof(szCurPath));_tstring strResult = szCurPath;return strResult;}_tstring CLogHelper::GetCurrentModuleDir(){return GetFileDir(GetCurrentModulePath());}_tstring CLogHelper::GetCurrentModuleName(bool bHasExt/* = true*/){return GetFileName(GetCurrentModulePath(), bHasExt);}_tstring CLogHelper::GetFileDir(const _tstring& strPath){_tstring strResult;size_t nIndex = strPath.find_last_of(_T('\\'));if (nIndex != _tstring::npos){strResult = strPath.substr(0, nIndex);}return strResult;}_tstring CLogHelper::GetFileName(const _tstring& strPath, bool bHasExt/* = true*/){_tstring strResult = strPath;size_t nIndex = strResult.find_last_of(_T('\\'));if (nIndex != _tstring::npos){strResult = strResult.substr(nIndex + 1);}if (!bHasExt){nIndex = strResult.find_last_of(_T('.'));if (nIndex != _tstring::npos){return strResult.substr(0, nIndex);}}return strResult;}bool CLogHelper::IsArchive(const _tstring& strPath){WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr)){return false;}return attr.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE;}bool CLogHelper::IsDirectory(const _tstring& strPath){WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr)){return false;}return attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;}bool CLogHelper::CreateDir(const _tstring& strPath){_tstring strDriver;              //驱动器号, 如 D:_tstring strSubPath = strPath;   //路径, 如 Test\1\2\3if (strPath.empty()){return false;}//获取盘符do{size_t nFindIndex = strPath.find_first_of(':');  //检查是否有驱动器号if (nFindIndex == _tstring::npos){break;}strDriver = strPath.substr(0, nFindIndex + 1); //得到驱动器号, 如 D:nFindIndex = strPath.find(_T("\\"), nFindIndex);if (nFindIndex == _tstring::npos){break;}strSubPath = strPath.substr(nFindIndex + 1); //得到路径, 如 Test\1\2\3} while (false);_tstring strDestDir;size_t nFindBegin = 0;size_t nFindIndex = 0;do{nFindIndex = strSubPath.find(_T("\\"), nFindBegin);if (nFindIndex != _tstring::npos){strDestDir = strSubPath.substr(0, nFindIndex);nFindBegin = nFindIndex + 1;}else{strDestDir = strSubPath;}if (!strDriver.empty()){strDestDir = strDriver + _T("\\") + strDestDir;}if (!::CreateDirectory(strDestDir.c_str(), NULL) && ERROR_ALREADY_EXISTS != ::GetLastError()){return false;}} while (nFindIndex != _tstring::npos);return true;}bool CLogHelper::DeleteArchive(const _tstring& strPath){if (strPath.empty()){return false;}return ::DeleteFile(strPath.c_str());}unsigned long long CLogHelper::GetFileSize(const _tstring& strPath){unsigned long long ullSize = 0;WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr)){return 0;}ullSize = (unsigned long long)attr.nFileSizeHigh << 32 | attr.nFileSizeLow;return ullSize;}}

使用

main.cpp

#include <iostream>
#include "CLogUtils.h"
#include <tchar.h>int _tmain(int argc, LPCTSTR argv[])
{while (true){uint64_t uBegin = CLogUtils::CLogHelper::GetCurrentTimestamp();uint64_t uEnd = 0;int nCount = 10000;std::cout << " CurrentTimestamp: " << uBegin << std::endl;for (int i = 0; i < nCount; i++){CLogUtils::LOG_INFO(_T("%d %s"), 1024, _T("FlameCyclone"));}uEnd = CLogUtils::CLogHelper::GetCurrentTimestamp();std::cout << "Repeat " << nCount << " Cost time: " << uEnd - uBegin << std::endl;system("pause");}return 0;
}

x64 Debug效果:

x64 Release效果:

http://www.hkea.cn/news/751047/

相关文章:

  • 小企业网站价格免费发链接的网站
  • 买了空间和域名 怎么做网站哪家公司网站做得好
  • 网站备案是否关闭衡阳网站建设公司
  • 遂昌建设局网站个人怎么做网站
  • 软件开发和网站建设网络营销的未来6个发展趋势
  • 做网站一年多少钱免费seo网站推广
  • 智通人才网东莞最新招聘信息官网seo是如何做优化的
  • 个人做跨境电商网站百度地图导航手机版免费下载
  • 阿里云注册网站之后怎么做网站百度联盟是什么
  • 动画制作视频河南网站排名优化
  • 网站关键词怎么做排名掌门一对一辅导官网
  • 现在什么网站做推广比较好网页设计需要学什么
  • 个人购物网站 怎么建网络营销包括
  • 有没有做鸭的网站工作室招聘广州网站优化工具
  • 深圳营销外深圳网络营销公司seo和sem的联系
  • 专业的网站制作公司哪家好竞价专员是做什么的
  • 海南省建设厅网站百度seo霸屏软件
  • 淄博张店做网站的公司爱站小工具圣经
  • wordpress w3seo优化自学
  • 临沂手机建站模板微信seo排名优化软件
  • 网站管理员怎么做板块建设艺人百度指数排行榜
  • 如何创建企业网站网络舆情处置的五个步骤
  • 做站长工具网站周口seo公司
  • 泉州自助建站系统地推
  • 美国 做网站免费网站建设哪家好
  • 如何做响应式布局网站seo搜索引擎优化期末及答案
  • 电脑系统优化软件十大排名北京网优化seo公司
  • 宁夏网站建设优化外贸网站优化推广
  • 开发网站开发工程师培训心得简短200字
  • 网站优化工具升上去软文营销代理