一、需求描述
在当前运行软件目录下,生成logs目录,输出上位机下发和接收的指令信息,按当前日期生成目录,再按小时生成日志文件,日志文件完整路径示例:D:\MC\MicroCtrl_G\x64\Release\logs\2024-08-05\11.txt
日志内容如下:
13:55:11.833 PUMP WRITE 3F 56 38 38 33 0D 00
13:55:11.985 PUMP READ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
13:55:12.702 PLATF WRITE FE FE 31 01 01 01 01 16
13:55:12.703 PLATF WRITE FE FE 31 01 01 01 01 16
二、C++ MFC版本
2.1 CLaserCtrl.h文件
#include <vector>
#include <fstream>
#include <afx.h>
#include <afxwin.h>
#include <iostream>
#include <iomanip> // 添加此头文件以使用 setfill 和 setw 函数
#include <string>
class __declspec(dllexport) CLaserCtrl
{
protected:
/************************************************************************
功能: 指令日志记录
输入: lpCmd:指令,如:{0x81, 0x31, 0x31,0x0D}
len:指令长度,如:4
sendReceiveType:1=下发指令;2=接收指令
isTimerCmd:是否为定时执行指令
************************************************************************/
void OutputCmdToFile(LPCSTR lpCmd, int len,int sendReceiveType,bool isTimerCmd);
bool IsTimerSendCmd(LPCSTR lpCmd, int len);
bool IsTimerReadCmd(LPCSTR lpCmd, int len);
// 创建日志目录,如:D:\MC\MicroCtrl_G\x64\Release\logs
CString CreateLogFolder();
// 创建目录
void CreateDirectory(LPCTSTR lpPath);
// 获取当前项目运行目录,如:D:\MC\MicroCtrl_G\x64\Release
CString pubGetCurrentDirectory();
}
2.2 CLaserCtrl.cpp文件
void CLaserCtrl::OutputCmdToFile(LPCSTR lpCmd, int len,int sendReceiveType,bool isTimerCmd) {
SYSTEMTIME st;
GetLocalTime(&st);
CStringA timeStr;
timeStr.Format("%02d", st.wHour);
CStringA timeFile(timeStr);
CString timerTag;
if(isTimerCmd)
{
timerTag= "_Timer";
}
CString filePath = CreateLogFolder() + "\\"+CString(timeFile)+ timerTag +".txt";
std::ofstream outFile(filePath,std::ios::app);
CStringA strTime;
strTime.Format("%02d:%02d:%02d.%03d", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
CStringA timeContent(strTime);
outFile << timeContent;
outFile <<" LASER";
if(sendReceiveType ==1)
{
outFile <<" WRITE ";
}else
{
outFile <<" READ ";
}
for (int i = 0; i < len; ++i) {
// 将十进制转换为十六进制并输出,不足两位用 0 填充
outFile << std::hex << std::uppercase << std::setfill('0') << std::setw(2) << (int)(unsigned char)lpCmd[i] << " ";
}
outFile << "\n";
outFile.close();
}
bool CLaserCtrl::IsTimerSendCmd(LPCSTR lpCmd, int len)
{
//23 21 40 55 56 32 46 0D 00
if (len == 9 && lpCmd[0] == 0x23 && lpCmd[1] == 0x21 && lpCmd[2] == 0x40 && lpCmd[3] == 0x55 && lpCmd[4] == 0x56 && lpCmd[5] == 0x32 && lpCmd[6] == 0x46 && lpCmd[7] == 0x0D && lpCmd[8] == 0x00) {
return true;
}
return false;
}
bool CLaserCtrl::IsTimerReadCmd(LPCSTR lpCmd, int len)
{
//3C 40 21 55
if (len > 4 && lpCmd[0] == 0x3C && lpCmd[1] == 0x40 && lpCmd[2] == 0x21 && lpCmd[3] == 0x55) {
return true;
}
return false;
}
CString CLaserCtrl::CreateLogFolder()
{
SYSTEMTIME st;
GetLocalTime(&st);
CStringA dayStr;
dayStr.Format("%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);
CStringA dayFolder(dayStr);
CString str = pubGetCurrentDirectory();
CString strFolder = pubGetCurrentDirectory()+_T("\\logs\\") + CString(dayFolder);
if (!PathFileExists(strFolder)) CreateDirectory(strFolder);
return strFolder;
}
CString CLaserCtrl::pubGetCurrentDirectory()
{
TCHAR pcDirectory[255];
GetModuleFileName(NULL , pcDirectory , 255);
CString strDirectory = pcDirectory;
strDirectory = strDirectory.Left(strDirectory.ReverseFind(_T('\\')));
return strDirectory;
}
void CLaserCtrl::CreateDirectory(LPCTSTR lpPath)
{
CString strPath(lpPath) , strPathTem;
std::vector<int> vnIndex;
for(int i=0; i<strPath.GetLength(); i++)
{
if(strPath[i] == _T('\\'))
{
vnIndex.push_back(i);
}
}
for(int i=0; i<vnIndex.size(); i++)
{
if(i == vnIndex.size() - 1)
{
strPathTem = strPath;
}
else
{
strPathTem = strPath.Left(vnIndex[i+1]);
}
if(!PathFileExists(strPathTem))
{
::CreateDirectory(strPathTem , NULL);
}
}
}
三、C++版本
3.1 PlatformCtrlAPI.h
#include <fstream>
#include <iostream>
#include <iomanip> // 添加此头文件以使用 setfill 和 setw 函数
#include <string>
#include <ctime>
#include <sstream>
/************************************************************************
功能: 指令日志记录
输入: lpCmd:指令,如:{0x81, 0x31, 0x31,0x0D}
len:指令长度,如:4
sendReceiveType:1=下发指令;2=接收指令
isTimerCmd:是否为定时执行指令
************************************************************************/
void OutputCmdToFile(char lpCmd[],int len,int sendReceiveType,bool isTimerCmd);
// 创建日志目录,如:D:\MC\MicroCtrl_G\x64\Release\logs
std::string CreateLogFolder();
// 创建目录
void CreateDirectory(std::string& lpPath);
// 获取当前项目运行目录,如:D:\MC\MicroCtrl_G\x64\Release
std::string PubGetCurrentDic();
// 判断当前目录是否存在
bool DirectoryExists(const std::string& path);
3.2 PlatformCtrlAPI.cpp
void OutputCmdToFile(char lpCmd[],int len,int sendReceiveType,bool isTimerCmd) {
std::string timerTag;
if(isTimerCmd)
{
timerTag= "_Timer";
}
// 获取当前系统时间
time_t now = time(0);
struct tm* localNow;
localNow = localtime(&now);
// 获取小时
char timeString[80];
strftime(timeString, sizeof(timeString), "%H", localNow);
// 构建文件夹路径
std::string timeStr = std::string(timeString);
std::string filePath = CreateLogFolder() + "\\"+timeStr+ timerTag +".txt";
std::ofstream outFile(filePath,std::ios::app);
//日志时间(到毫秒)
std::time_t nowTime = std::time(nullptr);
struct std::tm* localNowTime = std::localtime(&nowTime);
std::stringstream ss;
ss << std::setw(2) << std::setfill('0') << localNowTime->tm_hour << ":"
<< std::setw(2) << std::setfill('0') << localNowTime->tm_min << ":"
<< std::setw(2) << std::setfill('0') << localNowTime->tm_sec << "."
<< std::clock() % 1000;
outFile <<ss.str();
outFile <<" PLATF";
if(sendReceiveType ==1)
{
outFile <<" WRITE ";
}else
{
outFile <<" READ ";
}
for (int i = 0; i < len; ++i) {
// 将十进制转换为十六进制并输出,不足两位用 0 填充
outFile << std::hex << std::uppercase << std::setfill('0') << std::setw(2) << (int)(unsigned char)lpCmd[i] << " ";
}
outFile << "\n";
outFile.close();
}
std::string CreateLogFolder()
{
// 获取当前系统时间
time_t now = time(0);
struct tm* localNow;
localNow = localtime(&now);
// 格式化时间字符串
char timeString[80];
strftime(timeString, sizeof(timeString), "%Y-%m-%d", localNow);
// 构建文件夹路径
std::string dayStr = std::string(timeString);
std::string str = PubGetCurrentDic();
std::string strFolder = PubGetCurrentDic()+"\\logs\\" + dayStr;
CreateDirectory(strFolder);
return strFolder;
}
void CreateDirectory(std::string& lpPath)
{
bool logDicExists = DirectoryExists(lpPath);
if(logDicExists == false)
{
// 创建文件夹
if (CreateDirectory(lpPath.c_str(), NULL)) {
//成功
} else {
//失败
}
}
}
std::string PubGetCurrentDic()
{
TCHAR pcDirectory[255];
GetModuleFileName(NULL , pcDirectory , 255);
std::string strDirectory = pcDirectory;
size_t pos = strDirectory.rfind('\\');
if (pos!= std::string::npos) {
strDirectory = strDirectory.substr(0, pos);
}
return strDirectory;
}
bool DirectoryExists(const std::string& path) {
DWORD fileAttributes = GetFileAttributes(path.c_str());
if (fileAttributes == INVALID_FILE_ATTRIBUTES) {
return false;
}
return (fileAttributes & FILE_ATTRIBUTE_DIRECTORY)!= 0;
}
网友评论