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

posted on 2016-10-19 13:21  pospro  阅读(669)  评论(3)    收藏  举报

导航