windows编程递归遍历文件的方法

冷月清晖 程序员  2012-09-25 10:24:34
最近总看到windows开发初学者询问如何遍历目录里的文件,其实很简单的。

请参考我的blog:windows编程使用递归方法遍历文件的方法
...全文
276 点赞 收藏 32
写回复
32 条回复
冷月清晖 2012年09月27日
至于你说的 “各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会”完全是误导,你获取出来的非法文件名写入txt后再读出来处理,不还是一样有文件长度、后缀名等等问题啊!不还是要编写的纠错处理代码啊?!
回复 点赞
冷月清晖 2012年09月27日
[Quote=引用 26 楼 的回复:]

引用 16 楼 的回复:
引用 13 楼 的回复:

system("dir /b /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字
system("dir /b /s /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C……
[/Quote]

你这只是使用了批处理将文件夹下面的文件名输出到一个文件中,后面的处理再用api处理,先不论这种实现方式是否丑陋,对于一些问题也无法得到解决。比如:我的检索粒度需要精确到某个文件时,如果用你这种方式写一个文件到txt里面然后读出来再处理,是不是更丑?效率也低下。
还有比如:检查文件线程的优先级比较低,你一个批处理抛给system了,如何控制它的sleep?
还有各种各样问题,只想到这么多,就不一一列举了。
回复 点赞
赵4老师 2012年09月27日
[Quote=引用 16 楼 的回复:]
引用 13 楼 的回复:

system("dir /b /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字
system("dir /b /s /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C盘上所有文件的带全路径名字
s……
[/Quote]
仅供参考
//将c:\\tmp文件夹下的所有文件的内容全部放到用malloc分配的内存中
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
struct FB {
char fn[256];
size_t fl;
char *b;
struct FB *next;
struct FB *prev;
} *fh,*fb,*ft;
char ln[256];
char fpn[256];
FILE *af;
FILE *f;
int L,n;
int main() {
system("dir /b /a-d c:\\tmp\\*.* >c:\\allfn.txt");
af=fopen("c:\\allfn.txt","r");
if (NULL==af) {
printf("Can not open file c:\\allfn.txt!\n");
return 1;
}
fh=NULL;
fb=NULL;
n=0;
while (1) {
if (NULL==fgets(ln,256,af)) break;
L=strlen(ln);
if ('\n'==ln[L-1]) ln[L-1]=0;
printf("read %s\n",ln);
strcpy(fpn,"c:\\tmp\\");
strcat(fpn,ln);
ft=(struct FB *)malloc(sizeof(struct FB));
if (NULL==ft) {
printf("Can not malloc ft!\n");
fclose(af);
return 2;//之前的malloc在main退出后由操作系统自动free
}
printf("ft[%d]==%p\n",n,ft);
strcpy(ft->fn,fpn);
f=fopen(fpn,"rb");
if (NULL==f) {
printf("Can not open file %s!\n",fpn);
fclose(af);
return 3;//之前的malloc在main退出后由操作系统自动free
}
ft->fl=_filelength(fileno(f));
ft->b=malloc(ft->fl);
if (NULL==ft->b) {
printf("Can not malloc ft->b!\n");
fclose(f);
fclose(af);
return 4;//之前的malloc在main退出后由操作系统自动free
}
printf("ft[%d]->b==%p\n",n,ft->b);
if (ft->fl!=fread(ft->b,1,ft->fl,f)) {
printf("fread error!\n");
fclose(f);
fclose(af);
return 5;//之前的malloc在main退出后由操作系统自动free
}
fclose(f);
ft->next=NULL;

if (NULL==fh) {
ft->prev=NULL;
fh=ft;
} else {
fb->next=ft;
ft->prev=fb;
}
fb=ft;
n++;
}
fclose(af);
printf("-----list-----\n");
for (ft=fh;NULL!=ft;ft=ft->next) {
printf("%8d %s\n",ft->fl,ft->fn);
if (NULL!=ft) fb=ft;
}
printf("-----free-----\n");
n--;
if (NULL!=fh) {
for (ft=fb->prev;NULL!=ft;ft=ft->prev) {
if (NULL!=ft->next->b) {
printf("ft[%d]->b==%p\n",n,ft->next->b);
free(ft->next->b);
}
if (NULL!=ft->next) {
printf("ft[%d]==%p\n",n,ft->next);
free(ft->next);
}
n--;
}
if (NULL!=fh->b) {
printf("ft[0]->b==%p\n",fh->b);
free(fh->b);
}
printf("ft[0]==%p\n",fh);
free(fh);
}
return 0;
}
//C:\tmp\tmp\Debug>dir /a-d c:\tmp
// 驱动器 C 中的卷是 C_HD5_1
// 卷的序列号是 1817-D526
//
// c:\tmp 的目录
//
//找不到文件
//
//C:\tmp\tmp\Debug>tmp
//找不到文件
//-----list-----
//-----free-----
//
//C:\tmp\tmp\Debug>dir /a-d c:\tmp
// 驱动器 C 中的卷是 C_HD5_1
// 卷的序列号是 1817-D526
//
// c:\tmp 的目录
//
//2011-06-30 18:04 44,840 my_c.rar
//2011-06-30 17:18 1,036 err.frm
//2011-06-30 14:32 14,243 出租.txt
//2011-06-28 12:08 23,681 MSDN98书签.txt
// 4 个文件 83,800 字节
// 0 个目录 17,041,870,848 可用字节
//
//C:\tmp\tmp\Debug>tmp
//read my_c.rar
//ft[0]==00421800
//ft[0]->b==00520068
//read err.frm
//ft[1]==00421670
//ft[1]->b==0052AFC0
//read 出租.txt
//ft[2]==00421530
//ft[2]->b==00378F28
//read MSDN98书签.txt
//ft[3]==004213F0
//ft[3]->b==0052B3F8
//-----list-----
// 44840 c:\tmp\my_c.rar
// 1036 c:\tmp\err.frm
// 14243 c:\tmp\出租.txt
// 23681 c:\tmp\MSDN98书签.txt
//-----free-----
//ft[3]->b==0052B3F8
//ft[3]==004213F0
//ft[2]->b==00378F28
//ft[2]==00421530
//ft[1]->b==0052AFC0
//ft[1]==00421670
//ft[0]->b==00520068
//ft[0]==00421800
//
//C:\tmp\tmp\Debug>
回复 点赞
冷月清晖 2012年09月27日

想到的给100分。
回复 点赞
冷月清晖 2012年09月27日
道不同不相为谋,结贴!
回复 点赞
冷月清晖 2012年09月27日
不要转移话题。
回复 点赞
冷月清晖 2012年09月27日
[Quote=引用 29 楼 的回复:]

引用 28 楼 的回复:
至于你说的 “各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会”完全是误导,你获取出来的非法文件名写入txt后再读出来处理,不还是一样有文件长度、后缀名等等问题啊!不还是要编写的纠错处理代码啊?!

不妨用API试试遍历IE的临时文件夹。
[/Quote]

没那么无聊。
回复 点赞
赵4老师 2012年09月27日
[Quote=引用 28 楼 的回复:]
至于你说的 “各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会”完全是误导,你获取出来的非法文件名写入txt后再读出来处理,不还是一样有文件长度、后缀名等等问题啊!不还是要编写的纠错处理代码啊?!
[/Quote]
不妨用API试试遍历IE的临时文件夹。
回复 点赞
冷月清晖 2012年09月26日

if ( str1.GetLength() == 12 && _is_num(str1) )
{
ChkRecurse(str);//回调
}
else
{
Sleep(20);
continue;
}

有人问 这一段是干嘛用的,不好意思没有说明,这个回调是在一个线程里面跑的,而且这个线程的优先级并不高,基本上在系统空闲的时候做检查用的。至于文件夹名称长度为12,内容都为数字,这个是我的系统内部的约定,大家可以忽略。
回复 点赞
fthislife 2012年09月26日
[Quote=引用 22 楼 的回复:]
引用 21 楼 的回复:

引用 14 楼 的回复:
我的意思是 我要获得文件,比如 xxx.jpg等文件,然后进行特殊处理.

你们这样做是解决不了的。

char buf[256] = {0};
sprintf(buf,"dir /S /b %s\\xxx.jpg >path.txt",dir_name);//把查找得的xxx.jpg的路径存在path文件里
system(b……
[/Quote]
如果有时候确实想不到办法,管它丑与美,能用就行了。。想到的除外
回复 点赞
冷月清晖 2012年09月26日
需要我贴我的处理代码么?

要是都能用shell解决,你何必fopen呢?
回复 点赞
冷月清晖 2012年09月26日
[Quote=引用 21 楼 的回复:]

引用 14 楼 的回复:
我的意思是 我要获得文件,比如 xxx.jpg等文件,然后进行特殊处理.

你们这样做是解决不了的。

char buf[256] = {0};
sprintf(buf,"dir /S /b %s\\xxx.jpg >path.txt",dir_name);//把查找得的xxx.jpg的路径存在path文件里
system(buf);
FILE *fp……
[/Quote]

你不觉得这样做 很丑么?
回复 点赞
fthislife 2012年09月26日
[Quote=引用 14 楼 的回复:]
我的意思是 我要获得文件,比如 xxx.jpg等文件,然后进行特殊处理.

你们这样做是解决不了的。
[/Quote]
char buf[256] = {0};
sprintf(buf,"dir /S /b %s\\xxx.jpg >path.txt",dir_name);//把查找得的xxx.jpg的路径存在path文件里
system(buf);
FILE *fp=fopen("path.txt","r")
................
..............
回复 点赞
冷月清晖 2012年09月26日
[Quote=引用 19 楼 的回复:]

引用 13 楼 的回复:
system("dir /b /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字
system("dir /b /s /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C盘上所有文件的带全路径名字
s……
[/Quote]

膜拜个毛,上当还差不多。
回复 点赞
GBX99 2012年09月26日
[Quote=引用 13 楼 的回复:]
system("dir /b /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字
system("dir /b /s /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C盘上所有文件的带全路径名字
system("dir /b /a……
[/Quote]
膜拜一个
回复 点赞
nickwu1220 2012年09月25日
看代码。接分~~~
回复 点赞
珍惜生命远离CPP 2012年09月25日
回复 点赞
pathuang68 2012年09月25日
嗯,写得不赖。赞一个:)
回复 点赞
BUbuWander 2012年09月25日
没人,自己偷偷拿分。
回复 点赞
冷月清晖 2012年09月25日
沙发!板凳!
回复 点赞
发动态
发帖子
工具平台和程序库
创建于2007-09-28

8236

社区成员

2.7w+

社区内容

C/C++ 工具平台和程序库
社区公告
暂无公告