最近在做一个项目,使用C++写一个动态链接库(dll),里面需要有日志功能,于是参考网上的资料实现了C++写日志的功能。日志可以指定路径保存,也可以默认保存在当前可执行程序(exe)所在的文件夹。现在把源代码贴出来与大家共享,还请各位大神批评指正。
头文件:writeLog.h
-
/************************************************************************/
-
#ifndef _WRITELOG_H
-
#define _WRITELOG_H
-
-
#include <time.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <stdarg.h>
-
#include <Windows.h>
-
#include <memory.h>
-
-
#define LOG_WRITE_STATE 1 /*写日志条件,1:写日志,0:不写日志*/
-
-
#define LOG_SUCCESS 0 /*写日志成功标志*/
-
#define LOG_FAILED (-1) /*写日志失败标志*/
-
-
#define DWORD_NULL (0xFFFFFFFF)
-
-
#define MAX_LINE_LEN 1024 /*每行日志的最大长度*/
-
#define MAX_FILE_PATH 256 /*日志文件路径的最大长度*/
-
#define MAX_LOG_FILE_SIZE (512*1024) /*日志文件内容的最大长度*/
-
#define MAX_LOG_NAME_LEN 256 /*日志文件名的最大长度*/
-
-
#define LOG_TYPE_INFO 0 /*日志类型:错误类型*/
-
#define LOG_TYPE_SYSTEM 1 /*日志类型:系统类型*/
-
#define LOG_TYPE_ERROR 2 /*日志类型:错误类型*/
-
-
/*日志内容结构体*/
-
struct logData
-
{
-
char strDate[
11];
/*日期:格式为2014-07-01*/
-
char strTime[
9];
/*时间,格式为20:12:06*/
-
unsigned
char logType;
/*日志类型:INFO(0),SYSTEM(1),ERROR(2)*/
-
char logText[MAX_LINE_LEN];
/*每行的日志内容*/
-
};
-
#endif
源文件:writeLog.cpp
-
/************************************************************************/
-
#include "writeLog.h"
-
#include <io.h>
-
#include <direct.h>
-
-
int writeLogText(logData *pLogData);
/*写日志内容*/
-
void writeLog(unsigned char type, char *pStrText);
/*写日志*/
-
int createLogDir(char *pStrPath);
/*创建保存日志的路径*/
-
int createLogFile(const char *pStrPath, int iPos);
/*创建保存日志的文件夹*/
-
bool IsFileExist(const char *pStrFile);
/*判断文件是否存在*/
-
int getLogPath(char *pStrPath);
/*获取日志的路径*/
-
DWORD getFileLen(const char *pFile);
/*获取文件长度*/
-
int getLogFileName(int logType, const char *pStrPath, char *pStrName);
/*获取日志文件名*/
-
-
/************************************************************************/
-
/*
-
函数名称:int writeLogText(logData *pLogData)
-
说明:写日志内容
-
参数:pLogData是指向logData结构体的指针
-
返回值:LOG_SUCCESS(0)表示成功,LOG_FAILED(-1)表示失败
-
*/
-
/************************************************************************/
-
int writeLogText(logData *pLogData)
-
{
-
char filePath[MAX_FILE_PATH];
-
char fileName[MAX_LOG_NAME_LEN];
-
FILE *pFile =
NULL;
-
char logText[MAX_LINE_LEN];
-
memset(filePath,
0, MAX_FILE_PATH);
-
memset(fileName,
0, MAX_LOG_NAME_LEN);
-
memset(logText,
0, MAX_LINE_LEN);
-
getLogPath(filePath);
-
getLogFileName(pLogData->logType, filePath, fileName);
-
//pFile = fopen(fileName, "a+");
-
int r = fopen_s(&pFile, fileName,
"a+");
-
if(
NULL == pFile)
-
return LOG_FAILED;
-
sprintf_s(logText,
sizeof(logText),
"%s %s %s\n", pLogData->strDate, pLogData->strTime, pLogData->logText);
-
fwrite(logText,
1,
strlen(logText), pFile);
-
fclose(pFile);
-
return LOG_SUCCESS;
-
}
-
-
/************************************************************************/
-
/*
-
函数名称:void writeLog(unsigned char type, char *pStrText)
-
说明:写日志函数
-
参数:type:日志类型,pStrText:指向日志内容的指针
-
返回值:无
-
*/
-
/************************************************************************/
-
void writeLog(unsigned char type, char *pStrText)
-
{
-
logData data;
-
time_t currTime;
-
struct tm *mt;
-
memset(&data,
0,
sizeof(logData));
-
data.logType = type;
-
strcpy(data.logText, pStrText);
-
currTime = time(
NULL);
-
mt = localtime(&currTime);
-
strftime(data.strDate,
sizeof(data.strDate),
"%Y-%m-%d", mt);
-
strftime(data.strTime,
sizeof(data.strTime),
"%H:%M:%S", mt);
-
writeLogText(&data);
-
}
-
-
/************************************************************************/
-
/*
-
函数名:int createLogDir(char *pStrPath)
-
参数:pStrPath是用户指定的根路径
-
说明:创建日志存放路径
-
返回值:LOG_SUCCESS:成功
-
LOG_FAILED:失败
-
*/
-
/************************************************************************/
-
int createLogDir(char *pStrPath)
-
{
-
char *tag =
NULL;
-
for (tag = pStrPath;*tag !=
NULL;tag++)
-
{
-
if (
'\\' == *tag)
-
{
-
char path[MAX_FILE_PATH];
-
char buff[MAX_FILE_PATH];
-
strcpy(buff, pStrPath);
-
buff[
strlen(pStrPath) -
strlen(tag) +
1] =
NULL;
-
strcpy(path, buff);
-
if (_access(path,
0) ==
-1)
-
{
-
int r = _mkdir(path);
-
if (
-1 == r)
-
{
-
return LOG_FAILED;
-
}
-
}
-
}
-
}
-
return LOG_SUCCESS;
-
}
-
-
/************************************************************************/
-
/*
-
函数名:int createLogFile(const char *pStrPath, int iPos)
-
参数:pStrPath:文件名,iPos:文件指针位置
-
说明:创建日志文件
-
返回值:LOG_SUCCESS:成功
-
LOG_FAILED:失败
-
*/
-
/************************************************************************/
-
int createLogFile(const char *pStrPath, int iPos)
-
{
-
HANDLE hd =
0;
-
int iRet =
0;
-
if (
NULL == pStrPath)
-
{
-
return LOG_FAILED;
-
}
-
hd = CreateFile(pStrPath, GENERIC_READ | GENERIC_WRITE,
0,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
NULL);
-
if (INVALID_HANDLE_VALUE == hd)
-
{
-
return LOG_FAILED;
-
}
-
if (DWORD_NULL == SetFilePointer(hd, iPos,
NULL, FILE_BEGIN))
-
{
-
return LOG_FAILED;
-
}
-
iRet = SetEndOfFile(hd);
-
CloseHandle(hd);
-
return iRet;
-
}
-
-
/************************************************************************/
-
/*
-
函数名:bool IsFileExist(const char *pStrFile)
-
参数:pStrFile,文件名
-
说明:判断指定的文件是否存在
-
返回值:true:存在
-
false:不存在
-
*/
-
/************************************************************************/
-
bool IsFileExist(const char *pStrFile)
-
{
-
int iLen =
0;
-
WIN32_FIND_DATA findData;
-
memset(&findData,
0,
sizeof(WIN32_FIND_DATA));
-
HANDLE hd = FindFirstFile(pStrFile, &findData);
-
if (INVALID_HANDLE_VALUE == hd)
-
{
-
DWORD dwRet = GetLastError();
-
if (ERROR_FILE_NOT_FOUND == dwRet || ERROR_PATH_NOT_FOUND == dwRet)
-
{
-
return
false;
-
}
-
}
-
FindClose(hd);
-
return
true;
-
}
-
-
/************************************************************************/
-
/*
-
函数名:int getLogPath(char *pStrPath)
-
参数:pStrPath,文件名
-
说明:获取日志文件路径
-
返回值:LOG_SUCCESS:成功
-
LOG_FAILED:失败
-
*/
-
/************************************************************************/
-
int getLogPath(char *pStrPath)
-
{
-
if (
NULL == pStrPath)
-
{
-
return LOG_FAILED;
-
}
-
char currDir[MAX_FILE_PATH];
// = "F:\\writelog";
-
memset(currDir,
0, MAX_FILE_PATH);
-
int iRet =
0;
-
time_t currTime = time(
NULL);
-
struct tm *mt = localtime(&currTime);
-
/*根据日期组成文件夹名*/
-
GetModuleFileName(
NULL, currDir, MAX_FILE_PATH);
-
//(strrchr(currDir, '\\'))[1] = 0;
-
int temp =
0;
-
for (
int i =
sizeof(currDir);i >
0;i--)
-
{
-
if (currDir[i] ==
'\\')
-
{
-
temp = i;
-
break;
-
}
-
}
-
currDir[temp +
1] =
0;
-
sprintf(pStrPath,
"%s%d%02d%02d\\", currDir, mt->tm_year +
1900, mt->tm_mon +
1, mt->tm_mday);
-
iRet = createLogDir(pStrPath);
-
return iRet;
-
}
-
-
/*********************************************************************
-
* 函数名称:DWORD getFileLen(const char *pFile)
-
* 说明:获取指定的文件大小
-
* 输入参数:
-
* const char *pFile --文件名
-
* 返回值:
-
* DWORD -- 文件大小
-
*********************************************************************/
-
DWORD getFileLen(const char *pFile)
-
{
-
WIN32_FIND_DATA data;
-
HANDLE hd =
NULL;
-
memset(&data,
0,
sizeof(WIN32_FIND_DATA));
-
hd = FindFirstFile(pFile, &data);
-
FindClose(hd);
-
return (data.nFileSizeHigh * MAXDWORD) + data.nFileSizeLow;
-
}
-
-
/*********************************************************************
-
* 函数名称:int getLogFileName(int logType, const char *pStrPath, char *pStrName);
-
* 说明:获取日志文件名
-
* 输入参数:
-
* int logType -- 日志类型 3种:INFO(0)/ERROR(1)/SYSTEM(2)
-
* const char *pStrPath -- 日志路径 由getLogPath得到
-
* 输出参数:
-
* char *pStrName -- 日志文件名
-
* 返回值:
-
* int -- LOG_FAILED: 失败
-
* -- LOG_SUCCESS: 成功
-
*********************************************************************/
-
int getLogFileName(int logType, const char *pStrPath, char *pStrName)
-
{
-
if (
NULL == pStrPath)
-
{
-
return LOG_FAILED;
-
}
-
char logName[MAX_FILE_PATH];
-
FILE *pFile =
NULL;
-
memset(logName,
0, MAX_FILE_PATH);
-
switch(logType)
-
{
-
case LOG_TYPE_INFO:
-
sprintf_s(logName,
sizeof(logName),
"%s\\dll_log_info", pStrPath);
-
break;
-
case LOG_TYPE_ERROR:
-
sprintf_s(logName,
sizeof(logName),
"%s\\dll_log_error", pStrPath);
-
break;
-
case LOG_TYPE_SYSTEM:
-
sprintf_s(logName,
sizeof(logName),
"%s\\dll_log_system", pStrPath);
-
break;
-
default:
-
return LOG_FAILED;
-
break;
-
}
-
strcat(logName,
".txt");
-
if (IsFileExist(logName))
-
{
-
/*如果文件长度大于指定的最大长度,则重新创建一个文件覆盖原文件*/
-
if ((
int)getFileLen(logName) +
256 >= MAX_LOG_FILE_SIZE)
-
{
-
createLogFile(logName,
0);
-
}
-
}
-
else
-
createLogFile(logName,
0);
-
sprintf(pStrName,
"%s", logName);
-
return LOG_SUCCESS;
-
}
-
//测试代码
-
int main()
-
{
-
writeLog(LOG_TYPE_SYSTEM,
"program begin.");
-
return
0;
-
}
</div>