本文最后更新于 643 天前,其中的信息可能已经有所发展或是发生改变。
内容目录
/* 时间:2023/09/12 作者:马文杰 代码功能:存储文件之前,检查内存使用百分比,内存使用超过80%会自动删除最老旧的文件,以此来保证系统正常运行 函数名称: getLogUsePercentage / findMatchingFile / compareFileNames / delOldLogFile / main 历史: 日期:2023/09/21 作者:mawenjie 修改:函数delOldLogFile中有一处没有释放资源,是在combinedTime 申请资源失败时没有释放,文中已有记录标记。 */ #include <stdlib.h> #include <dirent.h> #include <stdio.h> #include <string.h> /* 函数功能: 获取系统指定路径下内存使用的百分比 */ int getLogUsePercentage() { int iUsePcent = -1; char line[512] = {0}; // 执行df命令并读取输出 FILE* pipe = popen("df /home/delphi/solo", "r"); if (pipe == NULL) { perror("Failed to execute df command"); exit(EXIT_FAILURE); } // 读取df命令的输出 while(fgets(line, sizeof(line), pipe)); printf("[+][%s:%d] line: %s\n",__FUNCTION__,__LINE__,line); // "56%" pclose(pipe); // 解析输出并提取百分比信息 sscanf(line, "%*s %*s %*s %*s %d%%", &iUsePcent); printf("[+][%s:%d] iUsePcent: %d\n",__FUNCTION__,__LINE__,iUsePcent); return iUsePcent; } /* 函数功能: 字符串匹配,根据字符串的一部分,匹配到一个完整的字符串(文件名称) */ char* findMatchingFile(const char* directory, const char* searchString) { DIR* dir = opendir(directory); if (dir == NULL) { printf("[+][%s:%d] 无法打开目录: %s\n",__FUNCTION__,__LINE__,directory); return NULL; } struct dirent* entry; while ((entry = readdir(dir)) != NULL) { if (entry->d_type == DT_REG) // 只处理普通文件 { char* fileName = entry->d_name; if (strstr(fileName, searchString) != NULL) // 匹配文件名 { char* filePath = malloc(strlen(directory) + strlen(fileName) + 2); // 分配足够的内存来存储文件路径 if (filePath == NULL) { closedir(dir); retturn NULL; } sprintf(filePath, "%s/%s", directory, fileName); closedir(dir); printf("[+][%s:%d] 匹配到的文件路径: %s\n",__FUNCTION__,__LINE__,filePath); return filePath; } } } closedir(dir); return NULL; // 没有找到匹配的文件 } /* 函数功能: qsort排序的规则 */ int compareFileNames(const void* a, const void* b) { return strcmp(*(const char**)a, *(const char**)b); } /* 函数功能: 删除旧的文件,保证存储文件之前,空间是足够的 */ void delOldLogFile(void) { // 删除路径下最老的文件 const char* logPath = "/home/delphi/solo"; char* combinedTime = NULL; int i = 0; struct dirent* entry; char** fileNames = NULL; int numFiles = 0; DIR* dir = opendir(logPath); if (dir == NULL) { printf("[+][%s:%d] 无法打开目录: %s\n",__FUNCTION__,__LINE__,logPath); return; } while ((entry = readdir(dir)) != NULL) { if (entry->d_type == DT_REG) // 只处理普通文件 { char* fileName = entry->d_name; if (strstr(fileName, ".log") != NULL) // 只处理以.log结尾的文件 { char* timePart = strtok(fileName, "_"); // 提取文件名中的时间部分 if (timePart != NULL) { // 判断文件名的数字部分的时间 char* secondPart = strtok(NULL, "_"); // 提取文件名中的第二部分 if (secondPart != NULL) { combinedTime = malloc(strlen(timePart) + strlen(secondPart) + 2); // 分配足够的内存来存储两个部分的时间 if (combinedTime == NULL) { closedir(dir); /* 2023/09/21修改 */ return; } strcpy(combinedTime, timePart); strcat(combinedTime, secondPart); long long fileTime = atoll(combinedTime); printf("[+][%s:%d] 文件组装: %s 文件转换成longlong类型:%d\n",__FUNCTION__,__LINE__,combinedTime,fileTime); if (fileTime != 0) { fileNames = realloc(fileNames, (numFiles + 1) * sizeof(char*)); fileNames[numFiles] = strdup(combinedTime); numFiles++; } free(combinedTime); } } } } } closedir(dir); if (numFiles == 0) { printf("[+][%s:%d] 目录: %s 中没有日志文件\n",__FUNCTION__,__LINE__,logPath); return; } // 按文件名进行排序 qsort(fileNames, numFiles, sizeof(char*), compareFileNames); // 看一下这个排序之后的输出结果对不对 for (i = 0; i < numFiles; i++) printf("[+] 排序结果fileNames:%s\n",fileNames[i]); // 获取最老的文件名 char* oldestFileNameNum = fileNames[0]; // 打印最老的文件名 20231201221202 -> 20231201_221202 char oldFileName[16]; strncpy(oldFileName, oldestFileNameNum, 8); oldFileName[8] = '_'; oldFileName[9] = '\0'; strcat(oldFileName, oldestFileNameNum + 8); printf("[+][%s:%d] 获取最老的文件名:%s\n",__FUNCTION__,__LINE__,oldFileName); // 这个文件还需要再文件夹中遍历,找到匹配的文件 20231201_221202 -> 20231201_221202_syslog_user.log const char* directory = "/home/delphi/solo"; char* oldestFilePath = findMatchingFile(directory, oldFileName); if (oldestFilePath != NULL) { printf("即将删除的文件: %s\n", oldestFilePath); remove(oldestFilePath); free(oldestFilePath); } else { printf("未找到匹配的文件\n"); } // 释放内存 for (i = 0; i < numFiles; i++) { free(fileNames[i]); } free(fileNames); return; } /* 函数功能:存储文件之前,检查内存使用概率,内存使用超过80%会自动删除最老旧的文件,以此来保证系统正常运行 */ int main() { int iUsePcent = -1; iUsePcent = getLogUsePercentage(); // 读取文件名称并删除旧文件,直到剩余空间达到20% if(iUsePcent > 80) printf("剩余空间不足,读取文件名称并删除旧文件\n"); while (iUsePcent > 80) { // TODO: 在此处添加读取文件名称和删除旧文件的代码 delOldLogFile(); // 更新使用的百分比 iUsePcent = getLogUsePercentage(); } // 保存文件 printf("剩余空间足够,保存文件\n"); // ... return 0; }
修改:函数delOldLogFile中有一处没有释放资源