c++保存最近n天文件夾

由於日誌庫沒有自動保存最近幾天日誌文件的處理函數。這幾天手動編寫一個保存最近n天的函數。,我寫的c++控制檯程序。

日誌模塊處理邏輯:
創建一個定時器每小時定時檢測當前時間。
每天的凌晨一點,就更新新的日誌文件和刪除舊的日誌文件:
1.按日期生成日誌文件夾和日誌文件
限制最大300m大小,可增長3次的日誌文件。
2.保留最近n天的日誌文件夾
① 獲取當前所有日誌文件夾的路徑
② 根據路徑獲取文件夾的創建時間
③ 根據文件夾的創建時間與當前時間進行比較,
這個就是日期相差天數的比較。
超出n天,則刪除該文件夾及所含文件。

#include <iostream>
#include <vector>
#include <io.h>  
#include <string>
#include <Windows.h>
#include <direct.h>  
using namespace std;

int monthdays[2][12] = { { 31,28,31,30,31,30,31,31,30,31,30,31 },{ 31,29,31,30,31,30,31,31,30,31,30,31 } };

int yeardays[2] = { 365,366 };

int isLearyear(int year)
{
	if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
		return 1;
	else
		return 0;
}
//日期靠前,當前日期
int caldays(int year1, int month1, int day1, int year2, int month2, int day2)
{
	int sumdays = 0;
	if (year1 == year2 && month1 == month2)
	{
		sumdays = day2 - day1;
	}
	else
		if (year1 == year2)
		{
			sumdays += monthdays[isLearyear(year1)][month1 - 1] - day1;
			//cout << " 1 :" << sumdays << endl;
			for (int i = month1; i < month2 - 1; i++)
				sumdays += monthdays[isLearyear(year1)][i];
			//cout << "2:" << sumdays << endl;
			sumdays += day2;
			//cout << "3 :" << sumdays << endl;
		}
		else
		{
			sumdays += monthdays[isLearyear(year1)][month1 - 1] - day1;
			for (int i = month1; i < 12; i++)
				sumdays += monthdays[isLearyear(year1)][i];


			for (int i = year1 + 1; i < year2; i++)
				sumdays += yeardays[isLearyear(i)];

			for (int i = 0; i < month2 - 1; i++)
				sumdays += monthdays[isLearyear(year2)][i];
			sumdays += day2;


		}
	return sumdays;
}


//獲取文件夾的創建時間
BOOL GetFileTime(HANDLE hFile, LPSTR lpszCreationTime)
{
	FILETIME ftCreate, ftAccess, ftWrite;
	SYSTEMTIME stUTC1, stLocal1;

	// 獲取 FileTime
	if (!GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite)) {
		cout << "error!" << endl;
		return FALSE;
	}
	//轉換: FileTime --> LocalTime
	FileTimeToSystemTime(&ftCreate, &stUTC1);

	SystemTimeToTzSpecificLocalTime(NULL, &stUTC1, &stLocal1);

	//獲取創建時間
	wsprintf(lpszCreationTime, "%02d/%02d/%02d  %02d:%02d",
		stLocal1.wYear, stLocal1.wMonth, stLocal1.wDay,
		stLocal1.wHour, stLocal1.wMinute);

	cout << "llvgiy" << endl;
	return TRUE;
}

//轉爲系統時間
string print(FILETIME ftime)
{
	char      str[50];
	SYSTEMTIME rtime;
	FILETIME            ltime;
	memset(str, 0, 50);
	//cout << "文件創建時間:" << ftime.dwHighDateTime << endl;
	//cout << "文件創建時間:" << ftime.dwLowDateTime << endl;


	FileTimeToLocalFileTime(&ftime, &ltime);

	FileTimeToSystemTime(&ltime, &rtime);        //將文件時間轉化爲系統時間

	sprintf(str, "%04u%02u%02u", rtime.wYear, rtime.wMonth, rtime.wDay);
	//printf("%s\n", str);
	return str;
}

//清空文件夾內所有文件
void deleteAllfiles(string deletepath)
{
	struct _finddata_t fileInfo;
	intptr_t hFile = _findfirst(deletepath.c_str(), &fileInfo);
	string p;
	if ((hFile = _findfirst(p.assign(deletepath).append("\\*").c_str(), &fileInfo)) != -1)
	{
		do
		{
			//如果是目錄,存入列表
			if ((fileInfo.attrib & _A_SUBDIR))
			{
				//是目錄
				if (strcmp(fileInfo.name, ".") != 0 && strcmp(fileInfo.name, "..") != 0)
				{
					//cout << "是mulu" << endl;
					continue;
					//filespath.push_back(p.assign(path).append("\\").append(fileInfo.name));
				}

			}
			else//是文件
			{
				//cout << p.assign(deletepath).append("\\").append(fileInfo.name) << endl;
				string deletefile = p.assign(deletepath).append("\\").append(fileInfo.name);
				remove(deletefile.c_str());
			}

		} while (_findnext(hFile, &fileInfo) == 0);

		_findclose(hFile);
	}
	//刪除目錄
	_rmdir(deletepath.c_str());
}


//比較文件夾創建時間進行刪除(保留n天日誌文件)
//日誌文件路徑-當前時間日期-保留的天數
void saveDays(string path,int saveday)
{
	//計算文件夾的個數和添加文件夾的名字
	vector<string> filespath;
	struct _finddata_t fileInfo;
	intptr_t hFile = _findfirst(path.c_str(), &fileInfo);
	string p;
	if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileInfo)) != -1)
	{
		do
		{
			//如果是目錄,存入列表
			if ((fileInfo.attrib & _A_SUBDIR))
			{
				//是目錄
				if (strcmp(fileInfo.name, ".") != 0 && strcmp(fileInfo.name, "..") != 0)
				{
					filespath.push_back(p.assign(path).append("\\").append(fileInfo.name));
				}
			}

		} while (_findnext(hFile, &fileInfo) == 0);

		_findclose(hFile);
	}

	//獲取文件夾的創建時間,和當前日期時間比較。
	vector<string> filescreatetime;
	for (int i = 0; i < filespath.size(); i++)
	{
		string folderpath = filespath[i];
		cout << "文件路徑:"<<folderpath << endl;

		//LPCSTR
		HANDLE hDir = CreateFile(folderpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
	/*	if (hDir == INVALID_HANDLE_VALUE)
		{
			printf("Get the dictionary failed!\n");
			CloseHandle(hDir);
			return;
		}*/
		//定義變量
		FILETIME                IpCreationTime;                 //文件夾的創建時間
		FILETIME                IpLastAccessTime;               //對文件夾的最近訪問時間
		FILETIME                IpLastWriteTime;                //文件夾的最近修改時間

		if (GetFileTime(hDir, &IpCreationTime, &IpLastAccessTime, &IpLastWriteTime))
		{
			filescreatetime.push_back(print(IpCreationTime));
		}
		CloseHandle(hDir);
	}

	//超出n天則進行刪除文件夾
	for (size_t i = 0; i < filescreatetime.size(); i++)
	{
		//計算文件與當前日期相差天數,超出則進行刪除
		//獲取當前時間
		//string curdate = gettime();
		//獲取毫秒級時間操作
		SYSTEMTIME sys;
		GetLocalTime(&sys);
		char chardate[50];
		sprintf_s(chardate, "%04d%02d%02d"
			, sys.wYear, sys.wMonth, sys.wDay
		);
		string curdate = chardate;

		int currentyear = stoi(curdate.substr(0,4));
		int currentmonth = stoi(curdate.substr(4, 2));
		int currentday = stoi(curdate.substr(6, 2));

		cout << "當前時間:" << currentyear<< " " << currentmonth<< " " << currentday << endl;
		//20200520--0-7
		int year = stoi(filescreatetime[i].substr(0, 4));
		int month = stoi(filescreatetime[i].substr(4, 2));
		int day = stoi(filescreatetime[i].substr(6, 2));

		cout << "文件創建時間:" << year << " "<<month << " " << day << endl;

		int sumday = caldays(year,month,day,currentyear, currentmonth,currentday);
		cout << "相差天數:" << sumday << endl;

		if ( sumday >= saveday)
		{
			cout << "刪除日誌文件夾,路徑"<< filespath[i] << endl;

			//刪除該日誌文件-以及目錄
			string deletepath = filespath[i];
			deleteAllfiles(deletepath);

		}
	}
}

int main()
{

	int num=0;
	//啓動定時器1h
	auto dairyTimer = SetTimer(NULL, 1, 3600*1000, NULL);
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (msg.message == WM_TIMER)
		{
			//獲取毫秒級時間操作
			SYSTEMTIME sys;
			GetLocalTime(&sys);
			char curtime[20];
			sprintf_s(curtime, "%02d", sys.wHour);
			string updatetime = curtime;
			//到凌晨一點執行刪除更新日誌文件
			if (updatetime == "01")
			{
				//自動保留7天日誌
				//日誌存放路徑和保留天數
				saveDays("log", 7);
				num++;
				cout << "執行次數: " << num << endl;
			}
		}
	}
	KillTimer(NULL, dairyTimer);

	return 0;
}

效果圖:
在這裏插入圖片描述

創建一個線程去啓動這個定時器,就能時刻對日誌文件夾進行處理啦。
創建日誌的部分看你自己使用的日誌庫。我就不貼上來了,網上都有。
至此,完成了保留最近n天日誌文件的處理。

這個程序是肯定存在有bug的地方。具體是哪些,大家可以互相交流學習一下。把這個程序完善好。

有大佬的話,可以在評論區留言告訴我。謝謝大家。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章