当前位置: 首页 > 科技观察

将前缀和后缀相同的文件移动到同一个目录的算法设计及C代码实现

时间:2023-03-21 13:35:59 科技观察

同目录下同前缀同后缀文件移动到同目录的算法设计及C代码实现。例如,有三个源目录FileDir1、FileDir2和FileDir3,其中分别存放文件File_1.txt、File_2.txt和File_3.txt。由于它们具有相同的前缀(File_)和后缀(txt),因此将这三个文件移动到相同的结果目录(假设为GatherDir)。2.算法设计根据需求,可以采用图1所示的程序流程:图1整体程序流程3.特殊流程注意事项在编写程序的过程中,一些特殊流程的注意事项如下:1.如果在扫描某个目录时出现错误,程序的运行将直接停止,不再继续扫描下一个目录。2、对于一些空文件(即文件大小为0),直接在源目录下删除,不移动到结果目录。3、为了能够随时处理放置在源目录下的文件,程序会每隔一段时间(比如一分钟)扫描源目录。也就是说,如果没有人为操作,程序启动后会一直运行下去。4.程序代码/***************************************************************************Copyright(C)2016,ZhouZhaoxion.**文件名:FileGather.c*文件ID:无*内容概要:将各目录下相同前缀的文件汇集到一个目录中*其他说明:无*当前版本:V1.0*作者:周兆雄*完成日期:20160513*************************************************************************/#include#include#include#include#include//重新定义数据类型typedefsignedintINT32;typedefunsignedintUINT32;typedefunsignedcharUINT8;//全局变量定义UINT8g_szGatherDir[256]={0};//汇总文件目录UINT8g_szFilePrefix[20]={0};//待汇总文件前缀UINT8g_szFileSuffix[20]={0};//待汇总文件后缀//宏定义#defineDIRNUM3//待扫描目录个数//函数声明INT32SelectFlies(structdirent*pDir);voidScanDirAndGather(void);voidSleep(UINT32iCountMs);/************************************************************************函数说明:主要函数*I输入参数:无*输出参数:无*返回值:0-执行完成*其他说明:无*修改日期版本号修改内容修改*--------------------------------------------------------------*20160513V1.0ZhouZhaoxiong创建*****************************************************************/INT32main(void){//获取摘要文件所在目录snprintf(g_szGatherDir,sizeof(g_szGatherDir)-1,"%s/zhouzx/TestDir/GatherDir",getenv("HOME"));//获取待汇总文件的前缀snprintf(g_szFilePrefix,sizeof(g_szFilePrefix)-1,"File_");//获取需要汇总的文件后缀snprintf(g_szFileSuffix,sizeof(g_szFileSuffix)-1,".txt");//调用函数执行文件汇总while(1){ScanDirAndGather();Sleep(60*1000);//每分钟执行一次文件摘要}return0;}/****************************************************************************功能说明:选择文件根据前缀和后缀*输入参数:dir-目录*输出参数:无*返回值:0-失败1-成功*其他说明:无*修改日期,版本号,修改人,修改内容*---------------------------------------------------------------------*20160513V1.0周兆雄创建*****************************************************************************/INT32SelectFlies(structdirent*pDir){INT32iPrefixLen=0;INT32iLoopF??lag=0;INT32iSelectResult=0;if(pDir==NULL){printf("SelectFlies:inputparameterisNULL!\n");return0;}//匹配文件前缀和后缀iPrefixLen=strlen(g_szFilePrefix);//前缀为g_szFilePrefixiSelectResult=((0==strncmp(pDir->d_name,g_szFilePrefix,iPrefixLen))&&((strncmp(&pDir->d_name[strlen(pDir->d_name)-strlen(g_szFileSuffix)],g_szFileSuffix,strlen(g_szFileSuffix))==0)));if(iSelectResult==1)//找到前缀匹配的文件{return1;}else{return0;}}/*****************************************************************************功能描述:扫描目录并汇总具有相同前缀的文件*输入参数:无*输出参数:无*返回值:无*其他说明:无*修改日期、版本号、修改人、修改内容*--------------------------------------------------------------------*20160513V1.0ZhouZhaoxion创建******************************************************************************/voidScanDirAndGather(无效){INT32iScanDirRet=0;UINT32iDirIdx=0;UINT32iFileIdx=0;UINT32iFileCount=0;UINT32iScanedNoFileDirCount=0;UINT32iFileSize=0;INT32iRetVal=0;UINT8szFileDir[256]={0};UINT8szScanedFile[512]={0};UINT8szCmdBuf[256]={0};FILE*fp=NULL;structdirent**ppDirEnt=NULL;//依次扫描每个目录并总结f文件(iDirIdx=1;iDirIdx<=DIRNUM;iDirIdx++){memset(szFileDir,0x00,sizeof(szFileDir));snprintf(szFileDir,sizeof(szFileDir)-1,"%s/zhouzx/TestDir/FileDir%d",getenv("HOME"),iDirIdx);iScanDirRet=scandir(szFileDir,&ppDirEnt,SelectFlies,alphasort);if(iScanDirRet<0)//扫描目录错误{printf("ScanDirAndGather:execscandirfailed,path=%s\n",szFileDir);return;}elseif(iScanDirRet==0)//目录下没有文件{printf("ScanDirAndGather:nosatisfiedfileindirectory%s\n",szFileDir);iScanedNoFileDirCount++;if(iScanedNoFileDirCount>=DIRNUM)//表示所有目录下都没有满足的文件{printf("ScanDirAndGather:scanednosatisfiedfilesinall%ddirs\n",iScanedNoFileDirCount);return;}}else//将满足条件的文件移至汇总目录{for(iFileIdx=0;iFileIdxd_name);fp=fopen(szScanedFile,"r");if(fp==NULL)//打开文件失败,直接return{printf("ScanDirAndGather:openfile%sfailed,pleasecheck!\n",szScanedFile);return;}fseek(fp,0,SEEK_END);iFileSize=ftell(fp);if(iFileSize==0)//文件为空文件{printf("ScanDirAndGather:%sisanemptyfile,sodeleteitdirectly!\n",szScanedFile);memset(szCmdBuf,0x00,sizeof(szCmdBuf));snprintf(szCmdBuf,sizeof(szCmdBuf)-1,"rm%s",szScanedFile);system(szCmdBuf));}else{memset(szCmdBuf,0x00,sizeof(szCmdBuf));snprintf(szCmdBuf,sizeof(szCmdBuf)-1,"mv%s%s",szScanedFile,g_szGatherDir);系统(szCmdBuf);printf("ScanDirAndGatherDir:now,%s\n",szCmdBuf);iFileCount++;}}}}printf("ScanDirAndGather:这次,totallymoved%dfile(s)to%s\n",iFileCount,g_szGatherDir);return;}/*******************************************************************************函数说明:程序睡眠*输入参数:iCountMs-睡眠时间(单位:ms)*输出参数:无*返回值:无*其他说明:无*修改日期版本号修改人修改内容*--------------------------------------------------------------------*20160513V1.0ZhouZhaoxiong创建***************************************************************************/voidSleep(UINT32iCountMs){structtimevalt_timeout={0};if(iCountMs<1000){t_timeout.tv_sec=0;t_timeout.tv_usec=iCountMs*1000;}else{t_timeout.tv_sec=iCountMs/1000;t_timeout.tv_usec=(iCountMs%1000)*1000;}select(0,NULL,NULL,NULL,&t_timeout);//调用select函数阻塞程序}五、将编写的程序测试将编写好的程序“FileGather.c”上传到Linux机器上,使用“gcc-g-oFileGatherFileGather.c”命令编译程序,生成“FileGather”文件以测试程序在细节。1、启动程序前,将文件File_1.txt、File_2.txt、File_3.txt分别放入源码目录FileDir1、FileDir2、FileDir3中。程序运行如下:ScanDirAndGather:now,mv/home/zhou/zhouzx/TestDir/FileDir1/File_1.txt/home/zhou/zhouzx/TestDir/GatherDirScanDirAndGather:now,mv/zhou/zhouzx/TestDir/FileDir3/File_3.txt/home/zhou/zhouzx/TestDir/GatherDirScanDirAndGather:这次,totallymoved3file(s)to/home/zhou/zhouzx/TestDir/GatherDir可以看到,源码目录下的三个文件都没有了,结果被移动了目录GatherDir:~/zhouzx/TestDir/GatherDir>ll-rw——-1zhouusers1222016-05-1315:14File_1.txt-rw——-1zhouusers122016-05-1315:14File_2。txt-rw——-1zhouusers1222016-05-1315:14File_3.txt2。一段时间后,将文件File1_4.txt放到源码目录FileDir1中,程序运行如下::nosatisfiedfileindirectorystory/home/zhou/zhouzx/TestDir/FileDir3ScanDirAndGather:scanednosatisfiedfilesinall3dirs可以看到,因为前缀不匹配,所以File1_4.txt文件还在源码目录FileDir1:~/zhouzx/TestDir/FileDir1>ll-rw——-1zhouusers362016-05-1315:19File1_4.txt3。一段时间后,将文件File_5.txt放入源码目录FileDir2,将文件File_11.c放入源码目录FileDir3,程序运行如下:ScanDirAndGather:nosatisfiedfileindirectory/home/zhou/zhouzx/TestDir/FileDir1ScanDirAndGather:now,mv/home/zhou/zhouzx/TestDir/FileDir2/File_5.txt/home/zhou/zhouzx/TestDir/GatherDirScanDirAndGather:nosatisfiedfileindirectory/home/zhou/zhouzx/TestDir/FileDir3ScanDirAndGather:thistime,totallymov)to/home/zhou/zhouzx/TestDir/GatherDir,可以看到源码目录FileDir2的文件File_5.txt没有了,因为后缀不匹配,源码目录FileDir3的文件File_11.c还存在:~/zhouzx/TestDir/FileDir3>ll-rw——-1zhouusers42016-05-1315:23File_11.cFile_5.txt已移动到结果目录GatherDir:~/zhouzx/TestDir/GatherDir>ll-rw——-1zhouusers1222016-05-1315:14File_1。txt-rw——-1zhouusers122016-05-1315:14File_2.txt-rw——-1zhouusers1222016-05-1315:14File_3.txt-rw——-1zhouusers362016-05-1315:23File_5.txt4。一段时间后,在源码目录FileDir2下放一个空文件File_7.txt,程序运行如下:/File_7.txt是一个空文件,直接删除!ScanDirAndGather:nosatisfiedfileindirectory/home/zhou/zhouzx/TestDir/FileDir3ScanDirAndGather:这次一共移动了0个文件到/home/zhou/zhouzx/TestDir/GatherDir,可以看到文件File_7.txt在源目录FileDir2已被删除:~/zhouzx/TestDir/FileDir2>lltotal06.需求扩展基于本文程序中的需求和需求,可以考虑对需求进行如下扩展:1.移动文件前,首先检查结果目录下是否存在同名文件,存在则直接删除源目录下的文件;如果不存在,则将该文件移动到结果目录下2.为避免结果目录下文件过多,可以在程序中加入清理机制,即删除存放时间超过一定时间的文件一段的时间。3、为了体现程序的灵活性,配置文件中可以保存一些文件信息(如文件前缀、后缀、存放目录、扫描间隔等)。目录扫描和文件移动操作。【本文为专栏作家周兆雄原创文章,作者微信公众号:周氏逻辑(logiczhou)】点此阅读更多本作者好文