• c/c++如何实现根据磁盘空间管理自己的日志文件案例


    目录

    一、本地日志文件管理设计

    二、案例实现

    三、案例代码设计

    四、编译实现

    五、附录说明


    一、本地日志文件管理设计

            在前文“c++中如何利用VA_LIST 和单体模式,构建自己的log小系统_py_free的博客-CSDN博客”中,简要创建了自己的log功能模块后,那么在系统长期运行过程中,会不断地创建日志文件并记录。对于微机、小型工控机等设备而言,存储空间是很宝贵的资源。为了节省空间,需要对日志文件进行管理,解决方法有不少,例如,日志文件远程推送后台、云端,或者不定时删除旧文件等等。

            在本文中,将设计一个磁盘管理功能模块,根据指定磁盘目录,如win指定{C,D},linux指定{/}等,获取磁盘总空间、剩余空间的数值,就可以依据存储空间来判定是否删除日志文件,为系统运行保持必要的空间。提供一个删除日志的API,根据指定目录和文件扩展名,去删除旧的日志文件。

    1. /**
    2. * 根据指定磁盘获取磁盘的总空间和剩余空间
    3. * @param _DiskStr {char} 磁盘目录,一般win指定{C,D},linux指定{/}
    4. * @param _totalSize {int} 返回磁盘总空间
    5. * @param _freeSize {int} 返回磁盘剩余空间
    6. * @return {int} 预留的返回值,暂指定是常量1
    7. */
    8. int getDiskFreeSpace(char _DiskStr, int &_totalSize, int &_freeSize);
    9. /**
    10. * 根据指定目录 扩展名 天数限制等删除目录下的文件,项目用于删除旧日志操作
    11. * @param _dir {string}} 目录
    12. * @param extname {string} 扩展名,如txt/ini/log等
    13. * @param dayForLimit_ {int} 指定天数,默认为0时会删除非当天的其他文件
    14. * @return {void} 无返回
    15. */
    16. void moveOldFile(std::string _dir, const std::string &extname, int dayForLimit_=0);
    17. /**
    18. * 获取当天凌晨时刻的偏移时间,单位秒,与1970-01-01 00:00:00起
    19. * @param deviation {int} 偏移秒数
    20. * @return {int} 当天凌晨时刻的偏移时间.单位秒
    21. */
    22. int getCurDayZeroClockTime(int deviation=0);

    二、案例实现

            在win中,提供类GetDiskFreeSpaceEx等API函数,获取与一个磁盘的组织有关的信息,以及了解剩余空间的容量。

    1. BOOL GetDiskFreeSpaceEx(
    2. LPCWSTR lpDirectoryName,
    3. PULARGE_INTEGER lpFreeBytesAvailableToCaller,
    4. PULARGE_INTEGER lpTotalNumberOfBytes,
    5. PULARGE_INTEGER lpTotalNumberOfFreeBytes
    6. );

            而在删除文件方面,可以先调用winAPI函数_findfirst来不断搜索与指定的文件名称匹配的第一个实例,若成功则返回第一个实例的句柄,并能获得_finddata_t结构化文件信息,然后依据扩展名、创建时间等确定是否删除该文件。

    1. #函数原型如下,需要包含
    2. long _findfirst( char *filespec, struct _finddata_t *fileinfo )

             在Linux中,提供了statfs或fstatfs的API函数来获取文件系统相关信息,

    1. #include /* 或者 */
    2. int statfs(const char *path, struct statfs *buf);
    3. int fstatfs(int fd, struct statfs *buf);
    4. #相关参数及statfs结构体说明
    5. path: 需要查询信息的文件系统的文件路径名。
    6. fd: 需要查询信息的文件系统的文件描述词。
    7. buf:以下结构体的指针变量,用于储存文件系统相关的信息
    8. struct statfs {
    9. long f_type; /* 文件系统类型 */
    10. long f_bsize; /* 经过优化的传输块大小,单位B*/
    11. long f_blocks; /* 文件系统数据块总数 */
    12. long f_bfree; /* 可用块数 */
    13. long f_bavail; /* 非超级用户可获取的块数 */
    14. long f_files; /* 文件结点总数 */
    15. long f_ffree; /* 可用文件结点数 */
    16. fsid_t f_fsid; /* 文件系统标识 */
    17. long f_namelen; /* 文件名的最大长度 */
    18. };

            而在删除日志文件的处理上,采用opendir、readdir来获得指定目录下各个文件信息“struct dirent”,然后依据扩展名、时间要求等判定是否删除。

    1. #include #include
    2. DIR *opendir(const char *name);
    3. struct dirent *readdir(DIR *dir);
    4. struct dirent
    5. {
    6. ino_t d_ino; //d_ino 此目录进入点的inode
    7. ff_t d_off; //d_off 目录文件开头至此目录进入点的位移
    8. signed short int d_reclen; //d_reclen _name 的长度, 不包含NULL 字符
    9. unsigned char d_type; //d_type d_name 所指的文件类型 d_name 文件名
    10. har d_name[256];
    11. };

    三、案例代码设计

            代码目录结构:

    1. log_test
    2. bin #编译目标输出目录
    3. build_win #win编译文件及中间文件目录
    4. build_linux #Linux编译文件及中间文件目录
    5. src #源码
    6. DiskSpace.h #磁盘空间计算、日志文件删除API集
    7. DiskSpace.cpp
    8. pyprint.h #采用宏定义实现的打印输出
    9. spaceMgr.h #基于DiskSpace函数集实现的磁盘管理线程,定期巡检磁盘并删除指定旧日志
    10. spaceMgr.cpp
    11. myThread.h #linux下线程类实现
    12. myThread.cpp
    13. win32Thread.h #win下线程类实现
    14. win32Thread.cpp
    15. main.cpp
    16. CMakeLists.txt #cmake工程配置文件

            DiskSpace.h:

    1. #if _MSC_VER > 1000
    2. #pragma once
    3. #endif // _MSC_VER > 1000
    4. #ifndef DISK_SPACE_H
    5. #define DISK_SPACE_H
    6. /***********************************************************************
    7. *Copyright 2022-09-20, pyfree
    8. *
    9. *File Name : DiskSpace.h
    10. *File Mark :
    11. *Summary :
    12. *磁盘空间统计和日志删除相关函数集
    13. *Current Version : 1.00
    14. *Author : pyfree
    15. *FinishDate :
    16. *
    17. *Replace Version :
    18. *Author :
    19. *FinishDate :
    20. ************************************************************************/
    21. #include
    22. namespace pyfree
    23. {
    24. /**
    25. * 根据指定磁盘获取磁盘的总空间和剩余空间
    26. * @param _DiskStr {char} 磁盘目录,一般win指定{C,D},linux指定{/}
    27. * @param _totalSize {int} 返回磁盘总空间
    28. * @param _freeSize {int} 返回磁盘剩余空间
    29. * @return {int} 预留的返回值,暂指定是常量1
    30. */
    31. int getDiskFreeSpace(char _DiskStr, int &_totalSize, int &_freeSize);
    32. /**
    33. * 根据指定目录 扩展名 天数限制等删除目录下的文件,项目用于删除旧日志操作
    34. * @param _dir {string}} 目录
    35. * @param extname {string} 扩展名,如txt/ini/log等
    36. * @param dayForLimit_ {int} 指定天数,默认为0时会删除非当天的其他文件
    37. * @return {void} 无返回
    38. */
    39. void moveOldFile(std::string _dir, const std::string &extname, int dayForLimit_=0);
    40. /**
    41. * 获取当天凌晨时刻的偏移时间,单位秒,与1970-01-01 00:00:00起
    42. * @param deviation {int} 偏移秒数
    43. * @return {int} 当天凌晨时刻的偏移时间.单位秒
    44. */
    45. int getCurDayZeroClockTime(int deviation=0);
    46. };
    47. #endif

    DiskSpace.cpp:

    1. #include "DiskSpace.h"
    2. #include
    3. #include
    4. #include
    5. #ifndef WIN32
    6. #include
    7. #include
    8. /*#include or */
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    16. #else
    17. #include
    18. #include
    19. #include
    20. #endif
    21. #include "pyprint.h"
    22. int pyfree::getDiskFreeSpace(char _DiskStr, int &_totalSize, int &_freeSize)
    23. {
    24. #ifdef WIN32
    25. BOOL fResult;
    26. unsigned _int64 i64FreeBytesToCaller;
    27. unsigned _int64 i64TotalBytes;
    28. unsigned _int64 i64FreeBytes;
    29. char dir[4] = { _DiskStr, ':', '\\' };
    30. //GetDiskFreeSpaceEx function,get the disk space status,return BOOL type
    31. fResult = GetDiskFreeSpaceEx(
    32. dir,
    33. (PULARGE_INTEGER)&i64FreeBytesToCaller,
    34. (PULARGE_INTEGER)&i64TotalBytes,
    35. (PULARGE_INTEGER)&i64FreeBytes);
    36. if (fResult)//jude the disk is in work status by the return value
    37. {
    38. _totalSize = static_cast<int>(static_cast<float>(i64TotalBytes) / 1024 / 1024); //disk total size
    39. _freeSize = static_cast<int>(static_cast<float>(i64FreeBytesToCaller) / 1024 / 1024); //disk free space sze
    40. MyPrint(L_NOTICE,"_totalSize(%ul) _freeSize(%ul)\n", _totalSize,_freeSize);
    41. }
    42. #endif // WIN32
    43. #ifdef __linux__
    44. //MyPrint(L_NOTICE,"DiskFlag(%c)\n", _DiskStr);
    45. struct statfs diskInfo;
    46. statfs("/", &diskInfo);
    47. unsigned long long totalBlocks = diskInfo.f_bsize;
    48. unsigned long long totalSize = totalBlocks * diskInfo.f_blocks;
    49. _totalSize = static_cast<int>(totalSize >> 20);
    50. //MyPrint(L_NOTICE,"TOTAL_SIZE == %d MB\n", _totalSize);
    51. unsigned long long freeDisk = diskInfo.f_bfree*totalBlocks;
    52. _freeSize = static_cast<int>(freeDisk >> 20);
    53. //MyPrint(L_NOTICE,"DISK_FREE == %d MB\n", _freeSize);
    54. #endif
    55. return 1;
    56. }
    57. //delete old file which is older taday for the file modify time
    58. void pyfree::moveOldFile(std::string _dir, const std::string &extname, int dayForLimit_)
    59. {
    60. try{
    61. MyPrint(L_NOTICE,"now will moveOldFile(*.%s) from(%s) \n",extname.c_str(),_dir.c_str());
    62. #ifdef WIN32
    63. _finddata_t fileInfo;
    64. intptr_t hFile;
    65. std::string filter = _dir;
    66. if (filter[filter.size() - 1] != '//' || filter[filter.size() - 1] != '\\') {
    67. filter.push_back('\\');
    68. }
    69. filter += "*.";
    70. filter += extname;
    71. //time_t file_time_ = time(NULL);
    72. time_t file_time_ = (time_t)getCurDayZeroClockTime(dayForLimit_*86400);
    73. //get
    74. hFile = _findfirst(filter.c_str(), &fileInfo);
    75. if (hFile == -1) {
    76. return;
    77. }
    78. std::string delOldFile = "";
    79. //find the oldest file by modify time
    80. do {
    81. if (extname.empty())//no ext name, that is dir
    82. {
    83. if ((fileInfo.attrib & _A_SUBDIR)) {
    84. if (0 == strcmp(fileInfo.name, ".") || 0 == strcmp(fileInfo.name, ".."))
    85. {
    86. continue;
    87. }
    88. }
    89. }
    90. //if(fileInfo.time_write<_time)//modify time
    91. if (fileInfo.time_create//create time
    92. {
    93. file_time_ = fileInfo.time_create;
    94. delOldFile = _dir + "//" + (std::string(fileInfo.name));
    95. }
    96. } while (_findnext(hFile, &fileInfo) == 0);
    97. _findclose(hFile);
    98. #endif
    99. #ifdef linux
    100. std::string curdir = _dir;
    101. if (curdir[curdir.size() - 1] != '/') {
    102. curdir.push_back('/');
    103. }
    104. DIR *dfd;
    105. if ((dfd = opendir(curdir.c_str())) == NULL)
    106. {
    107. MyPrint(L_WARNING,"open %s error with msg is: %s\n", curdir.c_str(), strerror(errno));
    108. return;
    109. }
    110. struct dirent *dp;
    111. //time_t file_time_ = time(NULL);
    112. time_t file_time_ = (time_t)getCurDayZeroClockTime(dayForLimit_ * 86400);
    113. std::string delOldFile = "";
    114. while ((dp = readdir(dfd)) != NULL)
    115. {
    116. if (extname.empty())//no ext name, that is dir
    117. {
    118. if (dp->d_type == DT_DIR) {
    119. if (0 == strcmp(dp->d_name, ".") || 0 == strcmp(dp->d_name, ".."))
    120. {
    121. continue;
    122. }
    123. }
    124. }
    125. else {
    126. if (NULL == strstr(dp->d_name, extname.c_str()))
    127. {
    128. continue;
    129. }
    130. }
    131. std::string _path = _dir + "/";
    132. _path += dp->d_name;
    133. struct stat el;
    134. stat(_path.c_str(), &el);
    135. if (el.st_mtime
    136. file_time_ = el.st_mtime;
    137. delOldFile = _path;
    138. }
    139. }
    140. if (NULL != dp) {
    141. delete dp;
    142. dp = NULL;
    143. }
    144. if (NULL != dfd) {
    145. closedir(dfd);
    146. dfd = NULL;
    147. }
    148. #endif
    149. if (!delOldFile.empty())
    150. {
    151. //MyPrint(L_NOTICE,"get old file: %s \n", delOldFile.c_str());
    152. int ret = remove(delOldFile.c_str());
    153. if (0 != ret) {
    154. MyPrint(L_WARNING,"can't remove %s \n", delOldFile.c_str());
    155. }else{
    156. MyPrint(L_NOTICE,"success remove %s \n", delOldFile.c_str());
    157. }
    158. }
    159. }catch(...){
    160. MyPrint(L_TRACE,"moveOldFile(*.%s) from(%s) exception error\n"
    161. ,extname.c_str(),_dir.c_str());
    162. }
    163. }
    164. int pyfree::getCurDayZeroClockTime(int deviation)
    165. {
    166. int ZeroClockTime_ = 0;
    167. time_t cur_time_ = time(NULL);
    168. struct tm _tt;
    169. #ifdef WIN32
    170. localtime_s(&_tt, &cur_time_);
    171. #else
    172. localtime_r(&cur_time_,&_tt);
    173. #endif
    174. //当日凌晨时刻
    175. _tt.tm_hour = 0;
    176. _tt.tm_min = 0;
    177. _tt.tm_sec = 0;
    178. ZeroClockTime_ = static_cast<int>(mktime(&_tt));
    179. ZeroClockTime_ -= deviation;//偏移时间
    180. return ZeroClockTime_;
    181. }

    pyprint.h:

    1. #if _MSC_VER > 1000
    2. #pragma once
    3. #endif // _MSC_VER > 1000
    4. #ifndef _PY_PRINT_H_
    5. #define _PY_PRINT_H_
    6. /***********************************************************************
    7. *Copyright 2022-09-20, pyfree
    8. *
    9. *File Name : pyprint.h
    10. *File Mark :
    11. *Summary : 打印输出通用宏定义
    12. *
    13. *Current Version : 1.00
    14. *Author : pyfree
    15. *FinishDate :
    16. *
    17. *Replace Version :
    18. *Author :
    19. *FinishDate :
    20. ************************************************************************/
    21. typedef enum PrintLevel
    22. {
    23. L_NOTICE = 1, //一般输出
    24. L_WARNING = 2, //告警输出
    25. L_TRACE = 3, //追踪调试
    26. L_DEBUG = 4, //软件bug
    27. L_FATAL = 5 //致命错误
    28. }PrintLevel;
    29. #define MyPrint(level,log_fmt,...) \
    30. do{ \
    31. switch(level) \
    32. { \
    33. case L_FATAL: \
    34. printf("L(5,FATAL)[%s:%d][%s] \n"log_fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
    35. break;\
    36. case L_DEBUG: \
    37. printf("L(4,DEBUG)[%s:%d][%s] \n"log_fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
    38. break;\
    39. case L_TRACE: \
    40. printf("L(3,TRACE)[%s:%d][%s] \n"log_fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
    41. break;\
    42. case L_WARNING: \
    43. printf("L(2,WARNING)[%s:%d][%s] \n"log_fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
    44. break;\
    45. case L_NOTICE: \
    46. printf("L(1,NOTICE)[%s:%d][%s] \n"log_fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
    47. break;\
    48. default: \
    49. printf("L(-1,UNKOWN)[%s:%d][%s] \n"log_fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
    50. break;\
    51. } \
    52. }while (0)
    53. #endif

    spaceMgr.h:

    1. #if _MSC_VER > 1000
    2. #pragma once
    3. #endif // _MSC_VER > 1000
    4. #ifndef _SPACE_MGR_H_
    5. #define _SPACE_MGR_H_
    6. /***********************************************************************
    7. *Copyright 2020-09-20, pyfree
    8. *
    9. *File Name : spaceMgr.h
    10. *File Mark :
    11. *Summary : 磁盘空间巡检线程类,根据预留空间要求删除app日志文件
    12. *
    13. *Current Version : 1.00
    14. *Author : pyfree
    15. *FinishDate :
    16. *
    17. *Replace Version :
    18. *Author :
    19. *FinishDate :
    20. ************************************************************************/
    21. #ifdef WIN32
    22. #include "win32Thread.h"
    23. #endif
    24. #ifdef linux
    25. #include
    26. #include "myThread.h"
    27. #endif
    28. #include
    29. class DiskSpaceMgr : public MyThread
    30. {
    31. public:
    32. /**
    33. * 构造函数,如传入参数D 2000 log log,则指明当D盘空闲空间不足2000M时,删除当前目录/log下的log(后缀)文件
    34. * @param disk_ {char} 指定盘符
    35. * @param fsl_ {int} 预留空间大小,单位MB
    36. * @param dir_ {string} 指定目录
    37. * @param ext_ {string} 扩展名
    38. * @return { }
    39. */
    40. DiskSpaceMgr(char disk_, int fsl_,std::string dir_="log",std::string ext_="log");
    41. virtual ~DiskSpaceMgr(void);
    42. int Run();
    43. void add(std::string dir_,std::string ext_);
    44. private:
    45. struct DelInfo
    46. {
    47. DelInfo(std::string dir_,std::string ext_)
    48. : dir(dir_), ext(ext_)
    49. {};
    50. std::string dir;
    51. std::string ext;
    52. };
    53. private:
    54. bool running;
    55. //用于日志删除
    56. std::vector dirs; //存储目录
    57. char DiskStr; //日志存储磁盘
    58. int freeSizeLimit; //磁盘预留空间要求
    59. };
    60. #endif

    spaceMgr.cpp:

    1. #include "spaceMgr.h"
    2. #ifdef WIN32
    3. #include
    4. #endif
    5. #ifdef linux
    6. #define Sleep(x) usleep(x*1000)
    7. #endif
    8. #include "DiskSpace.h"
    9. DiskSpaceMgr::DiskSpaceMgr(char disk_, int fsl_,std::string dir_/*="log"*/,std::string ext_/*="log"*/)
    10. : running(true)
    11. , DiskStr(disk_)
    12. , freeSizeLimit(fsl_)
    13. {
    14. DelInfo del_(dir_,ext_);
    15. dirs.push_back(del_);
    16. }
    17. DiskSpaceMgr::~DiskSpaceMgr(void)
    18. {
    19. running = false;
    20. }
    21. int DiskSpaceMgr::Run()
    22. {
    23. int _totalSize = 0;
    24. int _freeSize = 0;
    25. while (running)
    26. {
    27. if (pyfree::getDiskFreeSpace(DiskStr, _totalSize, _freeSize) > 0)
    28. {
    29. if (freeSizeLimit > _freeSize)
    30. {
    31. for(unsigned int i=0; isize(); ++i)
    32. {
    33. std::string ext = dirs.at(i).ext;
    34. pyfree::moveOldFile(dirs.at(i).dir, ext);
    35. }
    36. }
    37. }
    38. Sleep(10);
    39. }
    40. return 0;
    41. }
    42. void DiskSpaceMgr::add(std::string dir_,std::string ext_)
    43. {
    44. DelInfo del_(dir_,ext_);
    45. dirs.push_back(del_);
    46. }

    关于myThread.h 、 myThread.cpp、 win32Thread.h 、 win32Thread.cpp 文件以往文件都有,也一并给出

    myThread.h

    1. /*
    2. * add arg in linux system and compile: -lpthread
    3. *
    4. */
    5. #ifndef _MYTHREAD_H
    6. #define _MYTHREAD_H
    7. #include
    8. #include
    9. class MyThread
    10. {
    11. private:
    12. //current thread ID
    13. pthread_t tid;
    14. //thread status
    15. int threadStatus;
    16. //get manner pointer of execution
    17. static void* run0(void* pVoid);
    18. //manner of execution inside
    19. void* run1();
    20. public:
    21. //threadStatus-new create
    22. static const int THREAD_STATUS_NEW = 0;
    23. //threadStatus-running
    24. static const int THREAD_STATUS_RUNNING = 1;
    25. //threadStatus-end
    26. static const int THREAD_STATUS_EXIT = -1;
    27. // constructed function
    28. MyThread();
    29. ~MyThread();
    30. //the entity for thread running
    31. virtual int Run()=0;
    32. //start thread
    33. bool start();
    34. //gte thread ID
    35. pthread_t getThreadID();
    36. //get thread status
    37. int getState();
    38. //wait for thread end
    39. void join();
    40. //wait for thread end in limit time
    41. void join(unsigned long millisTime);
    42. };
    43. #endif /* _MYTHREAD_H */

    myThread.cpp

    1. #include "myThread.h"
    2. #include
    3. void* MyThread::run0(void* pVoid)
    4. {
    5. MyThread* p = (MyThread*) pVoid;
    6. p->run1();
    7. return p;
    8. }
    9. void* MyThread::run1()
    10. {
    11. threadStatus = THREAD_STATUS_RUNNING;
    12. tid = pthread_self();
    13. Run();
    14. threadStatus = THREAD_STATUS_EXIT;
    15. tid = 0;
    16. pthread_exit(NULL);
    17. }
    18. MyThread::MyThread()
    19. {
    20. tid = 0;
    21. threadStatus = THREAD_STATUS_NEW;
    22. }
    23. MyThread::~MyThread()
    24. {
    25. join(10);
    26. }
    27. int MyThread::Run()
    28. {
    29. while(true){
    30. printf("thread is running!\n");
    31. sleep(100);
    32. }
    33. return 0;
    34. }
    35. bool MyThread::start()
    36. {
    37. return pthread_create(&tid, NULL, run0, this) == 0;
    38. }
    39. pthread_t MyThread::getThreadID()
    40. {
    41. return tid;
    42. }
    43. int MyThread::getState()
    44. {
    45. return threadStatus;
    46. }
    47. void MyThread::join()
    48. {
    49. if (tid > 0)
    50. {
    51. pthread_join(tid, NULL);
    52. }
    53. }
    54. void MyThread::join(unsigned long millisTime)
    55. {
    56. if (tid == 0)
    57. {
    58. return;
    59. }
    60. if (millisTime == 0)
    61. {
    62. join();
    63. }else
    64. {
    65. unsigned long k = 0;
    66. while (threadStatus != THREAD_STATUS_EXIT && k <= millisTime)
    67. {
    68. usleep(100);
    69. k++;
    70. }
    71. }
    72. }

    win32Thread.h

    1. #if _MSC_VER > 1000
    2. #pragma once
    3. #endif // _MSC_VER > 1000
    4. #ifndef WIN32THREAD_H
    5. #define WIN32THREAD_H
    6. #include
    7. #include
    8. typedef void *HANDLE;
    9. class MyThread
    10. {
    11. public:
    12. MyThread();
    13. ~MyThread();
    14. void start();
    15. virtual int Run();
    16. HANDLE getThread();
    17. private:
    18. HANDLE hThread;
    19. static void agent(void *p);
    20. };
    21. #endif

    win32Thread.cpp

    1. #include "win32Thread.h"
    2. #include
    3. MyThread::MyThread()
    4. {
    5. }
    6. MyThread::~MyThread()
    7. {
    8. WaitForSingleObject(hThread, INFINITE);
    9. }
    10. void MyThread::start()
    11. {
    12. hThread =(HANDLE)_beginthread(agent, 0, (void *)this);
    13. }
    14. int MyThread::Run()
    15. {
    16. printf("Base Thread\n");
    17. return 0;
    18. }
    19. void MyThread::agent(void *p)
    20. {
    21. MyThread *agt = (MyThread *)p;
    22. agt->Run();
    23. }
    24. HANDLE MyThread::getThread()
    25. {
    26. return hThread;
    27. }

    main.cpp,磁盘空间获取及日志删除API使用示例

    1. #include
    2. #include
    3. #ifdef WIN32
    4. #include
    5. #endif
    6. #ifdef linux
    7. #define Sleep(x) usleep(x*1000)
    8. #endif
    9. #include "spaceMgr.h"
    10. int main(int argc, char *argv[])
    11. {
    12. //日志记录删除
    13. DiskSpaceMgr *ptr_DiskSpaceMgr = new DiskSpaceMgr('D',1200000
    14. ,"D:\\workForMy\\workspace\\log_test\\bin\\log","log");
    15. ptr_DiskSpaceMgr->start();
    16. int i = 0;
    17. while(i++<1)
    18. {
    19. Sleep(10);
    20. }
    21. delete ptr_DiskSpaceMgr;
    22. ptr_DiskSpaceMgr = NULL;
    23. return 0;
    24. }

    四、编译实现

            采用cmake组织工程文件:

    1. # CMake 最低版本号要求
    2. cmake_minimum_required (VERSION 2.8)
    3. # 项目信息
    4. project (log_mgr_test)
    5. #
    6. if(WIN32)
    7. message(STATUS "windows compiling...")
    8. add_definitions(-D_PLATFORM_IS_WINDOWS_)
    9. set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
    10. set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
    11. set(WIN_OS true)
    12. else(WIN32)
    13. message(STATUS "linux compiling...")
    14. add_definitions( -D_PLATFORM_IS_LINUX_)
    15. add_definitions("-Wno-invalid-source-encoding")
    16. # add_definitions("-O2")
    17. set(UNIX_OS true)
    18. set(_DEBUG true)
    19. endif(WIN32)
    20. #
    21. set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
    22. # 指定源文件的目录,并将名称保存到变量
    23. SET(source_h
    24. #
    25. ${PROJECT_SOURCE_DIR}/src/pyprint.h
    26. ${PROJECT_SOURCE_DIR}/src/DiskSpace.h
    27. ${PROJECT_SOURCE_DIR}/src/spaceMgr.h
    28. )
    29. SET(source_cpp
    30. #
    31. ${PROJECT_SOURCE_DIR}/src/DiskSpace.cpp
    32. ${PROJECT_SOURCE_DIR}/src/spaceMgr.cpp
    33. ${PROJECT_SOURCE_DIR}/src/main.cpp
    34. )
    35. #头文件目录
    36. include_directories(${PROJECT_SOURCE_DIR}/include)
    37. if (${UNIX_OS})
    38. SET(source_h_linux
    39. #
    40. ${PROJECT_SOURCE_DIR}/src/myThread.h
    41. )
    42. SET(source_cpp_linux
    43. ${PROJECT_SOURCE_DIR}/src/myThread.cpp
    44. )
    45. add_definitions(
    46. "-W"
    47. "-fPIC"
    48. "-Wall"
    49. # "-Wall -g"
    50. "-Werror"
    51. "-Wshadow"
    52. "-Wformat"
    53. "-Wpointer-arith"
    54. "-D_REENTRANT"
    55. "-D_USE_FAST_MACRO"
    56. "-Wno-long-long"
    57. "-Wuninitialized"
    58. "-D_POSIX_PTHREAD_SEMANTICS"
    59. "-DACL_PREPARE_COMPILE"
    60. "-Wno-unused-parameter"
    61. "-fexceptions"
    62. )
    63. set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
    64. link_directories()
    65. # 指定生成目标
    66. add_executable(log_mgr_test ${source_h} ${source_cpp} ${source_h_linux} ${source_cpp_linux})
    67. #link
    68. target_link_libraries(log_mgr_test
    69. -lpthread -pthread -lz -lrt -ldl
    70. )
    71. endif(${UNIX_OS})
    72. if (${WIN_OS})
    73. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4819")
    74. SET(source_h_win
    75. ${PROJECT_SOURCE_DIR}/src/win32Thread.h
    76. )
    77. SET(source_cpp_win
    78. ${PROJECT_SOURCE_DIR}/src/win32Thread.cpp
    79. )
    80. add_definitions(
    81. "-D_CRT_SECURE_NO_WARNINGS"
    82. "-D_WINSOCK_DEPRECATED_NO_WARNINGS"
    83. "-DNO_WARN_MBCS_MFC_DEPRECATION"
    84. "-DWIN32_LEAN_AND_MEAN"
    85. )
    86. link_directories()
    87. if (CMAKE_BUILD_TYPE STREQUAL "Debug")
    88. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)
    89. # 指定生成目标
    90. add_executable(log_mgr_testd ${source_h} ${source_cpp} ${source_h_win} ${source_cpp_win})
    91. else(CMAKE_BUILD_TYPE)
    92. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)
    93. # 指定生成目标
    94. add_executable(log_mgr_test ${source_h} ${source_cpp} ${source_h_win} ${source_cpp_win})
    95. endif (CMAKE_BUILD_TYPE)
    96. endif(${WIN_OS})

    win编译时采用cmake+vs编译,具体编译版本可以依据自身电脑安装版本决定

    1. cd log_mgr_test && mkdir build_win && cd build_win
    2. cmake -G "Visual Studio 10 2010 Win64" -DCMAKE_BUILD_TYPE=Release ..
    3. msbuild log_mgr_test.sln /p:Configuration="Release" /p:Platform="x64"

    运行效果类似:

    1. D:\workForMy\workspace\log_mgr_test\bin>log_mgr_test.exe
    2. L(1,NOTICE)[..\src\DiskSpace.cpp:45][pyfree::getDiskFreeSpace]
    3. _totalSize(939588l) _freeSize(112679l)
    4. L(1,NOTICE)[..\src\DiskSpace.cpp:69][pyfree::moveOldFile]
    5. moveOldFile(*.log) 1 from(D:\workForMy\workspace\log_test\bin\log)
    6. D:\workForMy\workspace\log_mgr_test\bin>

    Linux下

    1. cd log_mgr_test
    2. mkdir build_linux
    3. cd build_linux
    4. cmake ..
    5. make

    编译过程:

    1. [py@pyfree build_linux]$ cmake ..
    2. -- The C compiler identification is GNU 4.8.5
    3. -- The CXX compiler identification is GNU 4.8.5
    4. -- Check for working C compiler: /usr/bin/cc
    5. -- Check for working C compiler: /usr/bin/cc -- works
    6. -- Detecting C compiler ABI info
    7. -- Detecting C compiler ABI info - done
    8. -- Detecting C compile features
    9. -- Detecting C compile features - done
    10. -- Check for working CXX compiler: /usr/bin/c++
    11. -- Check for working CXX compiler: /usr/bin/c++ -- works
    12. -- Detecting CXX compiler ABI info
    13. -- Detecting CXX compiler ABI info - done
    14. -- Detecting CXX compile features
    15. -- Detecting CXX compile features - done
    16. -- linux compiling...
    17. -- Configuring done
    18. -- Generating done
    19. -- Build files have been written to: /mnt/hgfs/workForMy/workspace/log_mgr_test/build_linux
    20. [py@pyfree build_linux]$ make
    21. Scanning dependencies of target log_mgr_test
    22. [ 20%] Building CXX object CMakeFiles/log_mgr_test.dir/src/DiskSpace.cpp.o
    23. [ 40%] Building CXX object CMakeFiles/log_mgr_test.dir/src/spaceMgr.cpp.o
    24. [ 60%] Building CXX object CMakeFiles/log_mgr_test.dir/src/main.cpp.o
    25. [ 80%] Building CXX object CMakeFiles/log_mgr_test.dir/src/myThread.cpp.o
    26. [100%] Linking CXX executable ../bin/log_mgr_test
    27. [100%] Built target log_mgr_test
    28. [py@pyfree build_linux]$

    五、附录说明

    上面已经提供了完整的源文件,如果还不能实现,请去下载整个示例代码包:

    https://download.csdn.net/download/py8105/86570301

  • 相关阅读:
    一种亮红色染料AF 594 NHS Ester|295348-87-7|AF 594 Succinimidyl Ester
    Linux C应用编程-2-Makefile编写
    AI:77-基于深度学习的工业缺陷检测
    基于Java的大学生兼职论坛管理系统设计与实现(源码+lw+部署文档+讲解等)
    C++中的左值与右值
    算法竞赛进阶指南 0x58 数据结构优化DP
    温湿度阈值联网控制
    Java版企业电子招标采购系统源码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis
    [西湖论剑 2022]web部分题解(更新中ing)
    阿里云2核2G服务器e实例40G ESSD Entry系统盘99元一年
  • 原文地址:https://blog.csdn.net/py8105/article/details/126947879