关于遍历目录下面所有文件和文件夹的问题,请大家进来观光!

yiruirui0507 2010-07-08 09:34:02
// TraverseFile.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <iostream>

using namespace std;

//============声明遍历文件与文件夹的函数===============//
void TraverseFile(char *FileDirectory);

//====================main函数======================//
int main(int argc, char* argv[])
{
system("title 文件遍历器 By: yiruirui");
cout<<"Please input a file directory: ";
char FileDirectory[MAX_PATH];
cin>>FileDirectory;

//====开始调用====//
TraverseFile(FileDirectory);
system("pause");
return 0;
}


//============声明遍历文件与文件夹的函数===============//
void TraverseFile(char *FileDirectory)
{
char szFileName[MAX_PATH];
strcpy(szFileName,FileDirectory);
strcat(szFileName,"\\*.*");

WIN32_FIND_DATA FindData;
HANDLE hFile;
hFile = FindFirstFile(szFileName,&FindData);//这个FINDFIRESTFILE返回的听说是.和..为什么呢,太奇怪了


if(hFile != INVALID_HANDLE_VALUE)
{
if(FindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)//这里是否是判断文件还是文件夹?
{
if((strcmp(FindData.cFileName,".") != 0) && (strcmp(FindData.cFileName,"..") != 0)) //这里我调试发现FindData.cFileName=.,很好奇,因为我选的目录是c:\123里面根本没有文件夹,只有两个文件,为什么仍然是.
//..代表上一级目录,请高手帮忙详细说一下这里,或者推荐链接也可以,谢谢
{
char Dir[MAX_PATH];
strcpy(Dir,(char *)FileDirectory);
strcat(Dir,"\\");
strcat(Dir,(char *)FindData.cFileName);
cout<<"目录: "<<Dir<<endl;
}

}
else
{
char FileDir[MAX_PATH];
strcpy(FileDir,(char *)FileDirectory);
strcat(FileDir,"\\");
strcat(FileDir,(char *)FindData.cFileName);
cout<<"文件: "<<FileDir<<endl;
}

while (FindNextFile(hFile,&FindData))
{
if(FindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)//如果是文件夹则继续执行
{
if((strcmp(FindData.cFileName,".") != 0) && (strcmp(FindData.cFileName,"..") != 0))
{
char Dir[MAX_PATH];
strcpy(Dir,(char *)FileDirectory);
strcat(Dir,"\\");
strcat(Dir,(char *)FindData.cFileName);
cout<<"目录: "<<Dir<<endl;

//==递归调用==//
TraverseFile(Dir);
}

}
else
{
char FileDir[MAX_PATH];
strcpy(FileDir,(char *)FileDirectory);
strcat(FileDir,"\\");
strcat(FileDir,(char *)FindData.cFileName);
cout<<"文件: "<<FileDir<<endl;
}
}
FindClose( hFile );


}
else
{
cout<<"Invalid file directory !"<<endl;
}

}
这句话 if((strcmp(FindData.cFileName,".") != 0) && (strcmp(FindData.cFileName,"..") != 0)) 就没理解了,还望高手详细说明,先谢谢!
...全文
331 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
yiruirui0507 2010-07-10
  • 打赏
  • 举报
回复
这两个比较忙,忘记结贴了,不好意思了~
jbz001 2010-07-08
  • 打赏
  • 举报
回复
好,看看~!
写的不错~!
baihacker 2010-07-08
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 yiruirui0507 的回复:]
引用 22 楼 baihacker 的回复:
if((strcmp(FindData.cFileName,".") != 0)
按你19楼的提问,通过这一步,应该过滤掉了表示当前目录的特殊文件夹,但是没有过滤掉表示上级目录的。
假定这里已经过滤掉了,那么后面的的不应该出现形如.,..的文件夹。
在假定过滤掉的情况下:
FindData.cFileName
应该是1.txt
然后是2.……
[/Quote]
按我的程序,如果枚举出来的文件名第一个字符是.(包含了.和..这两种情况),于是就下一步枚举。
然后把文件名和其路径组合起来放到Result里。
结合你的问题,把FindFileData.cFileName 输出了一次。

一切正常。
cattycat 2010-07-08
  • 打赏
  • 举报
回复
if((strcmp(FindData.cFileName,".") != 0) && (strcmp(FindData.cFileName,"..") != 0))

这个可以过滤掉.和..,因为你是循环和递归的,所以第一次是.和..,后面就不是了,再进入子目录的时候还是要if这里判断一下忽略掉.和..的目录。

你的程序执行起来没问题啊。
yiruirui0507 2010-07-08
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 baihacker 的回复:]
if((strcmp(FindData.cFileName,".") != 0)
按你19楼的提问,通过这一步,应该过滤掉了表示当前目录的特殊文件夹,但是没有过滤掉表示上级目录的。
假定这里已经过滤掉了,那么后面的的不应该出现形如.,..的文件夹。
在假定过滤掉的情况下:
FindData.cFileName
应该是1.txt
然后是2.txt

以c:\123作为查找目录 .……
[/Quote]
首先感谢搂着如此 辛苦的写了这个函数指针,你写的这个
if (*FindFileData.cFileName == '.') continue;
::_stprintf(Result, _T("%s\\%s"), szSourceDir, FindFileData.cFileName);
cout << FindFileData.cFileName << endl;

没理解清楚!既然你也说是在假定的情况下,不应该输出.和..的文件夹,可你代码中出现了.所以我还是不明白,我比较笨,请别生气!
baihacker 2010-07-08
  • 打赏
  • 举报
回复
if((strcmp(FindData.cFileName,".") != 0)
按你19楼的提问,通过这一步,应该过滤掉了表示当前目录的特殊文件夹,但是没有过滤掉表示上级目录的。
假定这里已经过滤掉了,那么后面的的不应该出现形如.,..的文件夹。
在假定过滤掉的情况下:
FindData.cFileName
应该是1.txt
然后是2.txt

以c:\123作为查找目录 .当然就相当于c:\123



#include <cstdio>
#include <cstring>
#include <iostream>
#include <tchar.h>
#include <windows.h>
using namespace std;

typedef long long int64;

typedef void (*ENUM_FILES_FUNCTION)(const TCHAR*, LPWIN32_FILE_ATTRIBUTE_DATA);

#define SYS_IS_DIRECTORY(f) (f & FILE_ATTRIBUTE_DIRECTORY)
#define SYS_IS_HIDDEN(f) (f & FILE_ATTRIBUTE_HIDDEN)
#define SYS_IS_READONLY(f) (f & FILE_ATTRIBUTE_READONLY)
#define SYS_IS_SYSTEM(f) (f & FILE_ATTRIBUTE_SYSTEM)
void EnumFiles(const TCHAR* szSourceDir, ENUM_FILES_FUNCTION callback_fun)
{
if (!szSourceDir) return;

WIN32_FIND_DATA FindFileData;
WIN32_FILE_ATTRIBUTE_DATA FindFileAttr;
HANDLE hFind = INVALID_HANDLE_VALUE;
TCHAR currDir[MAX_PATH];
TCHAR Result[MAX_PATH];

_tcsncpy(currDir, szSourceDir, _tcslen(szSourceDir) + 1);
_tcsncat(currDir, _T("\\*"), 3);

hFind = FindFirstFile(currDir, &FindFileData);

if (hFind == INVALID_HANDLE_VALUE) return;
do
{
if (*FindFileData.cFileName == '.') continue;
::_stprintf(Result, _T("%s\\%s"), szSourceDir, FindFileData.cFileName);
cout << FindFileData.cFileName << endl;
if (callback_fun && GetFileAttributesEx(Result, GetFileExInfoStandard, &FindFileAttr))
{
(*callback_fun)(Result, &FindFileAttr);
}
} while (FindNextFile(hFind, &FindFileData));
}


int main()
{
EnumFiles("d:\\123", 0);
return 0;
}



上面的程序正如期望那样输出
1.txt
2.txt
yiruirui0507 2010-07-08
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 cattycat 的回复:]
你没看我的回复吗,每个文件夹下都有两个目录,一个是.,一个是..,即使是空文件夹也这样。这是文件系统实现的,linux下也这样,形成树形目录,可以向下,也可以返回到上级目录。你用dir命令,就可以看到前两个是.和..
[/Quote]
很好,那如果你这样说,是不是每次
FindFirstFile(szFileName,&FindData);//
if((strcmp(FindData.cFileName,".") != 0)
FindData.cFileName都等于.呢?如果不是,请帮忙分析,谢谢!
cattycat 2010-07-08
  • 打赏
  • 举报
回复
你没看我的回复吗,每个文件夹下都有两个目录,一个是.,一个是..,即使是空文件夹也这样。这是文件系统实现的,linux下也这样,形成树形目录,可以向下,也可以返回到上级目录。你用dir命令,就可以看到前两个是.和..
yiruirui0507 2010-07-08
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 baihacker 的回复:]
引用 14 楼 yiruirui0507 的回复:
命运如此喜欢玩弄人,到此没有一个回答让我满意的,真的很无语,并不是我要求高啊,而是那些所谓知道的人他们到底知不知道那谁知道呢,回答的一个比一个沧桑。

哪里不清楚了?
[/Quote]
我详细告诉你我哪里不清楚,希望你耐心听完。比如我查找的目录是C:\123
123目录中只有两个文件1.txt,2.txt,请问这个时候
FindFirstFile(szFileName,&FindData);//
if((strcmp(FindData.cFileName,".") != 0)
这里的FindData.cFileName等于多少?为什么还是.?123里面根本就没有文件夹啊!!
我认为FindData.cFileName应该等于c:\123\1.txt,这里的.就相当于c:\123请问对吗?
baihacker 2010-07-08
  • 打赏
  • 举报
回复
d:\Projects>dir
驱动器 D 中的卷没有标签。
卷的序列号是 0091-E414

d:\Projects 的目录

2010/07/08 09:41 <DIR> .
2010/07/08 09:41 <DIR> ..
cattycat 2010-07-08
  • 打赏
  • 举报
回复
每个文件夹下有两个特殊的目录, .和..,前者表示当前目录,后者是上一级目录,就是父目录。
strcmp那个就是判断目录不是当前和父目录的意思。
如果想继续深入,学习一下操作系统的文件系统的东西吧。
baihacker 2010-07-08
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 yiruirui0507 的回复:]
命运如此喜欢玩弄人,到此没有一个回答让我满意的,真的很无语,并不是我要求高啊,而是那些所谓知道的人他们到底知不知道那谁知道呢,回答的一个比一个沧桑。
[/Quote]
哪里不清楚了?
aaabc 2010-07-08
  • 打赏
  • 举报
回复
. 可以说是一个BUG 比如你 MD \MM..\ 这个文件夹就不能正常访问!
yiruirui0507 2010-07-08
  • 打赏
  • 举报
回复
命运如此喜欢玩弄人,到此没有一个回答让我满意的,真的很无语,并不是我要求高啊,而是那些所谓知道的人他们到底知不知道那谁知道呢,回答的一个比一个沧桑。
mamchao 2010-07-08
  • 打赏
  • 举报
回复
去C++区问去。
baihacker 2010-07-08
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 yiruirui0507 的回复:]
引用 10 楼 baihacker 的回复:
.是一个特殊文件夹的名字。。。

请问到底有什么特殊?能举例 吗?
[/Quote]
如我7楼所示
yiruirui0507 2010-07-08
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 baihacker 的回复:]
.是一个特殊文件夹的名字。。。
[/Quote]
请问到底有什么特殊?能举例 吗?
赵4老师 2010-07-08
  • 打赏
  • 举报
回复
system("cmd /c dir /a-d /b /s /on c:\\mydir\\*.* >c:\\allfiles.txt");
//然后读c:\\allfiles.txt的内容
baihacker 2010-07-08
  • 打赏
  • 举报
回复
.是一个特殊文件夹的名字。。。
yiruirui0507 2010-07-08
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 baihacker 的回复:]
引用 6 楼 yiruirui0507 的回复:
引用 3 楼 baihacker 的回复:
.表示当前目录,..表示父级目录,这里是把这两个忽略掉的意思。

我也听说是系统隐藏的,但是我想知道的是一些细节,毕竟听说还不是很清楚啊,当然了其实这个问题我不问也无所谓的,我可以把它记住,但是我感觉没有任何意思。

#include "./xx/fuck.h"
#include "../.……
[/Quote]
if((strcmp(FindData.cFileName,".") != 0) && (strcmp(FindData.cFileName,"..") != 0))

这里前边已经限定了文件属性是FILE_ATTRIBUTE_DIRECTORY,也就是文件夹了,那这里应该返回的是第一个文件夹的名字才对啊,FindData.cFileName就是第一个文件夹名字才对,为什么我调试是.哪里有问题?
你只写#include ....跟我的问题好像没关系吧??
加载更多回复(8)

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧