根据分发到不同目录的前缀将源目录下的文件分发到不同目录的算法设计和C代码实现。例如在源目录SourceDir中存放三个相同后缀的文件File1_1.txt、File2_1.txt和File3_1.txt,根据前缀File1_分别移动(分发)到目录FileDir1、FileDir2和FileDir3中,文件2_和文件3_。2.算法设计根据需求,可以采用图1所示的程序流程:图1整体程序流程3.特殊流程注意事项在编写程序的过程中,一些特殊流程的注意事项如下:1.如果源目录扫描出现错误,程序的运行将直接停止,不再继续扫描下一个目录。2、对于一些空文件(即文件大小为0),直接在源码目录下删除,不分配。3、为了能够随时处理放置在源目录下的文件,程序会每隔一段时间(比如一分钟)扫描源目录。也就是说,如果没有人为操作,程序启动后会一直运行下去。4.程序代码/***************************************************************************Copyright(C)2016,ZhouZhaoxion.**文件名:FileDistribute.c*文件ID:无*内容概要:将一个目录下的文件按前缀分发到对应目录*其他说明:无*当前版本:V1.0*作者:周兆雄*完成日期:20160517*************************************************************************/#include#include#include#include#include//重定义数据类型typedefsignedintINT32;typedefunsignedintUINT32;typedefunsignedcharUINT8;//全局变量定义UINT8g_szSourceDir[256]={0};//源文件目录//函数声明INT32SelectFlies(structdirent*pDir);voidScanDirAndDistribute(void);voidSleep(UINT32iCountMs);/************************************************************************函数说明:主要函数*输入参数:无*输出参数:无*返回值:0-执行完成*其他说明:无*修改日期版本号修改内容修改*----------------------------------------------------------*20160517V1.0ZhouZhaoxion创建*******************************************************************/INT32main(void){//源文件所在目录snprintf(g_szSourceDir,sizeof(g_szSourceDir)-1,"%s/zhouzx/TestDir/SourceDir",getenv("HOME"));//调用函数执行文件分发while(1){ScanDirAndDistribute();Sleep(60*1000);//每分钟执行一次文件分发}return0;}/*********************************************************************************功能说明:根据需要选择文件到后缀*输入参数:dir-目录*输出参数:无*返回值:0-失败1-成功*其他说明:需要扫描test.txt这样的文件,但是test这样的文件不符合条件*修改日期版本号修改人修改内容*------------------------------------------------------------------*20160517V1.0ZhouZhaoxiongCreated****************************************************************************/INT32SelectFlies(structdirent*pDir){if(pDir==NULL){printf("SelectFlies:inputparameterisNULL!\n");return0;}//根据.txt(后缀)选择文件if(strstr(pDir)->d_name,".txt")!=NULL){return1;//查找满足条件的文件}else{return0;}}/********************************************************************************功能说明ion:扫描目录并分发文件*输入参数:无*输出参数:无*返回值:无*其他说明:无*修改日期版本号修改内容修改*-----------------------------------------------------------------*20160517V1.0ZhouZhaoxiong创建**************************************************************************/voidScanDirAndDistribute(void){INT32iScanDirRet=0;UINT32iFileIdx=0;UINT32iFileCount=0;UINT32iFileSize=0;UINT8szFileDir[256]={0};UINT8szScanedFile[512]={0};UINT8szCmdBuf[256]={0};FILE*fp=NULL;structdirent**ppDirEnt=NULL;//扫描源目录,分发文件iScanDirRet=scandir(g_szSourceDir,&ppDirEnt,SelectFlies,alphasort);if(iScanDirRet<0)//扫描目录错误{printf("ScanDirAndDistribute:execscandirfailed,path=%s\n",g_szSourceDir);return;}elseif(iScanDirRet==0)//目录下没有文件{printf("ScanDirAndDistribute:nosatisfiedfileindirectory%s\n",g_szSourceDir);}else//移动文件满足条件的进入对应目录{for(iFileIdx=0;iFileIdxd_name);fp=fopen(szScanedFile,"r");if(fp==NULL)//操作失败n文件,直接返回{printf("ScanDirAndDistribute:openfile%sfailed,pleasecheck!\n",szScanedFile);返回;}fseek(fp,0,SEEK_END);iFileSize=ftell(fp);如果(iFileSize==0)//文件为空文件{printf("ScanDirAndDistribute:%sisanemptyfile,sodeleteitdirectly!\n",szScanedFile);memset(szCmdBuf,0x00,sizeof(szCmdBuf));snprintf(szCmdBuf,sizeof(szCmdBuf)-1,"rm%s",szScanedFile);system(szCmdBuf);}else//根据前缀{if(strncmp(ppDirEnt[iFileIdx]->d_name,"File1_",strlen("File1_"))==0)//移动到FileDir1{memset(szFileDir,0x00,sizeof(szFileDir));snprintf(szFileDir,sizeof(szFileDir)-1,"%s/zhouzx/TestDir/FileDir1",getenv("HOME"));}elseif(strncmp(ppDirEnt[iFileIdx]->d_name,"File2_",strlen("File2_"))==0)//移动到FileDir2{memset(szFileDir,0x00,sizeof(szFileDir));snprintf(szFileDir,sizeof(szFileDir)-1,"%s/zhouzx/TestDir/FileDir2",getenv("HOME"));}elseif(strncmp(ppDirEnt[iFileIdx]->d_name,"File3_",strlen("File3_"))==0)//移动到FileDir3{memset(szFileDir,0x00,sizeof(szFileDir));snprintf(szFileDir,sizeof(szFileDir)-1,"%s/zhouzx/TestDir/FileDir3",getenv("HOME"));}else//前缀不满足,直接删除文件{memset(szCmdBuf,0x00,sizeof(szCmdBuf));snprintf(szCmdBuf,sizeof(szCmdBuf)-1,"rm%s",szScanedFile);system(szCmdBuf);printf("ScanDirAndDistribute:now,%s\n",szCmdBuf);continue;//继续判断下一个}memset(szCmdBuf,0x00,sizeof(szCmdBuf));snprintf(szCmdBuf,sizeof(szCmdBuf)-1,"mv%s%s",szScanedFile,szFileDir);system(szCmdBuf);printf("ScanDirAndDistribute:now,%s\n",szCmdBuf);iFileCount++;}}}printf("ScanDirAndDistribute:thistime,totallymoved%dfile(s).\n",iFileCount);return;}/*****************************************************************************函数说明:程序休眠*输入参数:iCountMs-休眠时间(单位:ms)*输出参数:无*返回值:无*其他说明:无*修改日期,版本号,修改人,修改内容*------------------------------------------------------------*20160517V1.0ZhouZhaoxiong创建***********************************************************************/voidSleep(UINT32iCountMs){structtimevalt_timeout={0};如果(我CountMs<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函数阻塞程序}5.程序测试将写好的程序“FileDistribute.c”上传到linux机器上,使用“gcc-g-oFileDistributeFileDistribute.c”命令到程序编译并生成“FileDistribute”文件来详细测试程序。1、启动程序前,将文件File1_1.txt、File2_1.txt、File3_1.txt放到源码目录SourceDir中,程序运行状态如下:ScanDirAndDistribute:now,mv/home/zhou/zhouzx/TestDir/SourceDir/文件1_1。txt/home/zhou/zhouzx/TestDir/FileDir1ScanDirAndDistribute:now,mv/home/zhou/zhouzzx/TestDir/SourceDir/File2_1.txt/home/zhou/zhouzx/TestDir/FileDir2ScanDirAndDistribute:now,mv/home/zhou/zhouzx/TestDir/SourceDir/File3_1.txt/home/zhou/zhouzx/TestDir/FileDir3ScanDirAndDistribute:这次一共移动了3个文件。可以看到source目录下的三个文件都没有了,分别被移动到了结果目录FileDir1和FileDir2中,并且在FileDir3中:~/zhouzx/TestDir/SourceDir>lltotal0~/zhouzx/TestDir/FileDir1>ll-rw-------1zhouusers1222016-05-1718:58File1_1.txt~/zhouzx/TestDir/FileDir2>ll-rw------1zhouusers122016-05-1718:58File2_1.txt~/zhouzx/TestDir/FileDir3>ll-rw--------1zhouusers122016-05-1718:58File3_1.txt2。稍等片刻,在源码目录SourceDir中放入文件File4_1.txt,程序运行如下:.1212可以看到直接删除了File4_1.txt文件,因为前缀不匹配~/zhouzx/TestDir/SourceDir>lltotal012123。一段时间后,放入空文件File_7.txt、File_8.txt和File_9.txt,程序运行如下:home/zhou/zhouzx/TestDir/SourceDir/File_8.txtib是个空文件,直接删除!直接删除!home/zhou/zhouzx/TestDir/SourceDir/File_9.txt是一个空文件,所以直接删除!ScanDirAndDistribute:这次,一共移动了0个文件。可以看到源码目录SourceDir中的所有空文件都被删除了。~/zhouzx/TestDir/SourceDir>lltotal012126.需求扩展根据本文的需求和流程,需求可以考虑扩展如下:1.移动(分发)文件前,首先检查相同的文件文件名在对应的结果目录下如果存在,直接删除源目录下的文件;如果不存在,则将该文件移动到相应的结果目录。2、为了避免结果目录中文件过多,可以在程序中加入清理机制,即删除存放时间超过一定时间的文件。3、为了体现程序的灵活性,配置文件中可以保存一些文件信息(如文件前缀、后缀、存放目录、扫描间隔等)。目录扫描和文件分发操作。【本文为专栏作家周兆雄原创文章,作者微信公众号:周氏逻辑(logiczhou)】点此阅读更多本作者好文