C语言实现Windows7下的文件清单生成器
一、引子
朋友提出这样一个需求:快速获得某个文件夹(及其子文件夹)内全部的文件名。
事情的起因是这样的,他正在按公司的要求整理一个项目的佐证材料,按照不同的检查项,应把相关材料放在不同的文件夹中。但是最终还是需要一份所有材料的清单。由于佐证材料经常需要更新和变动,他想要一种简单的方法快速获得这份清单(记录每个文件夹下的所有文件名)。
二、思路分析
(一)我最初想到的方法是直接在DOS模式下找到相应文件夹,然后输入:
dir /s >filesout.txt
生成的结果如下:

虽然所有文件和文件夹都很清晰地显示出来,但并未达到朋友的要求。主要是因为:
1. 上图的输出是先把一个层级内的全部文件和文件夹都输出,然后再把每个文件夹内下一层级的内容逐次输出。朋友希望像树形展开图那样地直观体现文件层级。
2. 存在.和..这样无意义的文件夹信息,而且日期、文件大小并不是朋友想要的信息。
(二)采用编程实现
A. 程序逻辑:很简单,就是一个递归。
1. 给定起始目录
2. 递归函数
首先判断输入的文件名是文件还是文件夹
2.1 若为文件,则输出文件名
2.2 若为文件夹,则首先输出文件夹名,并将该文件夹名作为参数,递归调用本身这个函数
B. 实现过程中遇到的问题
1. 计划利用C语言完成,但很快就发现,虽然C语言提供了读文件和写文件的函数,但并不提供文件夹管理之类的函数,因为这些函数是操作系统相关的!由于计划在Windows7下使用,索引必须查找Windows API,具体可以参考:
https://msdn.microsoft.com/en-us/library/windows/desktop/ff818516(v=vs.85).aspx
针对文件和文件夹查找,Windows API给出以下两个函数:FindFirstFile、FindNextFile
2. 使用Windows API,需要#include <windows.h>,好在PosPro目前使用的是Codeblock IDE,自带了这个头文件,省去了不少麻烦。
3. 为了实现傻瓜式操作,朋友要求把exe文件放到需要生成清单的文件夹下,双击运行,生成一个记录文件清单的TXT文件。所以需要GetCurrentDirectory函数来获得当前路径。
4. 特别提示,对于FileFirstFile函数,要提供绝对路径,并且在最后要增加“\*”,否则搜索可能无法获得正常结果
三、程序实现
源代码如下:
1 /* 2 2016.10.18 by PosPro 3 功能: 4 按照文件夹层级输出当前文件夹下全部文件名信息, 5 以<>表示文件夹名 6 生成结果保存在当前目录的_IndexOut.txt文件中 7 8 使用方法: 9 把exe文件放到需生成清单的文件夹下,双击运行即可 10 */ 11 #include <stdlib.h> 12 #include <stdio.h> 13 #include <windows.h> 14 #include <tchar.h> 15 16 FILE *outfile; //一个全局变量,以便各层递归都可以直接使用 17 18 void printFileMap(TCHAR *fn, int level); //递归函数 19 20 void main(){ 21 22 outfile=fopen("_IndexOut.txt","w"); //最终结果保存在此文件中 23 24 TCHAR szBuf[MAX_PATH]; //存储当前路径 25 GetCurrentDirectory(MAX_PATH, szBuf); 26 _tcscat(szBuf,_T("\\")); //上句中获得的路径不包括(\),这里加上 27 28 printf("请稍候,工作完成后本对话框会自动关闭\n"); //在DOS提示框中输出的信息 29 printf("生成结果见当前目录下新生成的文件: _IndexOut.txt\n"); 30 printf("WORKING...Please Wait...\n"); 31 32 printFileMap(szBuf, 0); //启动递归函数 33 34 fprintf(outfile, "\n\n\n===Programmed By PosPro 2016.10.18=======\n"); 35 fprintf(outfile, "========Thanks for using=================\n"); 36 fclose(outfile); 37 } 38 39 40 void printFileMap(TCHAR* fn, int level){ 41 WIN32_FIND_DATA FindFileData, nextFileData; //以此结构体保存文件信息 42 HANDLE hFind; 43 44 TCHAR searchFilePath[MAX_PATH]; 45 _tcscpy(searchFilePath, fn); 46 _tcscat(searchFilePath, _T("*")); //必须在搜索路径后加入通配符(*), FindFirstFile才能正常运行 47 48 hFind=FindFirstFile(searchFilePath, &FindFileData); 49 if (hFind != INVALID_HANDLE_VALUE){ //如果为空文件夹,或者文件不存在,则不进入 50 do{ 51 if(FindFileData.dwFileAttributes!=FILE_ATTRIBUTE_DIRECTORY){ //如果为文件,则打印文件名 52 int i; 53 for(i=level; i>0; i--) //根据不同层级,打印空格以错开位置 54 fprintf(outfile," "); 55 fprintf(outfile, "%s\n",FindFileData.cFileName); 56 } 57 else{ 58 if(_tcscmp(FindFileData.cFileName,_T("."))&&_tcscmp(FindFileData.cFileName,_T(".."))) 59 //实现对.和..这两个文件夹的过滤 60 { 61 TCHAR nextf[MAX_PATH]; 62 int i; 63 for(i=level; i>0; i--) 64 fprintf(outfile, " "); 65 fprintf(outfile, "<%s>\n",FindFileData.cFileName); 66 67 //必须构建出绝对路径,才能做下一步搜索! 68 _tcscpy(nextf, fn); 69 _tcscat(nextf, FindFileData.cFileName); 70 _tcscat(nextf,_T("\\")); 71 printFileMap(nextf, level+1); 72 } 73 } 74 }while(FindNextFile(hFind, &FindFileData)); 75 } 76 77 FindClose(hFind); 78 }
最后生成清单示例:

更多文章可见:http://blog.csdn.net/pospro
浙公网安备 33010602011771号