C++遍历目录文件

typedef struct _WIN32_FIND_DATAW{
	DWORD dwFileAttributes;		//一个文件(或路径)的文件属性。
	FILETIME ftCreationTime;
	FILETIME ftLastAccessTime;
	FILETIME ftLastWriteTime;
	DWORD nFileSizeHigh;
	DWORD nFileSizeLow;
	DWORD dwReserved0;
	DWORD dwReserved1;
	_Field_z_ WCHAR  cFileName[MAX_PATH];
	_Field_z_ WCHAR  cAlternateFileName[14];
#ifdef _MAC
	DWORD dwFileType;
	DWORD dwCreatorType;
	WORD  wFinderFlags;
#endif
} WIN32_FIND_DATAW;
  1. DWORD dwFileAttributes; //一个文件(或路径)的文件属性。

    FILE_ATTRIBUTE_ARCHIVE32(0x20)作为存档文件或目录的文件或目录。应用程序通常使用此属性标记文件以进行备份或删除。

    FILE_ATTRIBUTE_COMPRESSED2048(0x800)压缩的文件或目录。对于文件,压缩文件中的所有数据。对于目录,压缩是新创建的文件和子目录的默认设置。

    FILE_ATTRIBUTE_DIRECTORY16(0x10)标识目录的句柄。

    FILE_ATTRIBUTE_ENCRYPTED16384(0x4000)加密的文件或目录。对于文件,文件中的所有数据流都是加密的。对于目录,加密是新创建的文件和子目录的默认设置。

    FILE_ATTRIBUTE_HIDDEN2(0x2)隐藏文件或目录。它不包含在普通目录列表中。

    FILE_ATTRIBUTE_NORMAL128(0x80)未设置其他属性的文件。此属性仅在单独使用时有效。

    FILE_ATTRIBUTE_NOT_CONTENT_INDEXED8192(0x2000)文件或目录不由内容索引服务编制索引。

    FILE_ATTRIBUTE_NO_SCRUB_DATA131072(0x20000)用户数据流不被后台数据完整性扫描程序(AKA scrubber)读取。在目录上设置时,它仅提供继承。仅在存储空间和ReFS卷上支持此标志。它不包含在普通目录列表中。
    Windows Server 2008 R2,Windows 7,Windows Server 2008,Windows Vista,Windows Server 2003和Windows XP:在Windows 8和Windows Server 2012之前不支持此标志。

    FILE_ATTRIBUTE_OFFLINE4096(0x1000)文件的数据不可立即生效。此属性指示文件数据已物理移动到脱机存储。该属性由远程存储使用,远程存储是分层存储管理软件。应用程序不应随意更改此属性。

    FILE_ATTRIBUTE_READONLY1(0x1)只读文件。应用程序可以读取文件,但无法写入或删除它。目录上不支持此属性。有关详细信息,请参阅Windows Server 2003,Windows XP,Windows Vista或Windows 7中无法查看或更改文件夹的只读或系统属性。

    FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS4194304(0x400000)设置此属性后,表示文件或目录未完全存在于本地。对于一个文件,这意味着并非所有数据都在本地存储上(例如,它可能很稀疏,某些数据仍在远程存储中)。对于目录,这意味着某些目录内容正在从另一个位置进行虚拟化。读取文件/枚举目录将比正常情况更昂贵,例如它将导致至少从远程存储中获取一些文件/目录内容。只有内核模式调用者才能设置此位。

    FILE_ATTRIBUTE_RECALL_ON_OPEN262144(0x40000)此属性仅出现在目录枚举类(FILE_DIRECTORY_INFORMATION,FILE_BOTH_DIR_INFORMATION等)中。设置此属性后,表示文件或目录在本地系统上没有物理表示形式;该项目是虚拟的。打开物品将比正常情况更昂贵,例如它会导致至少从远程商店中取出一部分内容。

    FILE_ATTRIBUTE_REPARSE_POINT1024(0x400)具有关联重分析点的文件或目录,或者是符号链接的文件。

    FILE_ATTRIBUTE_SPARSE_FILE512(0x200)作为稀疏文件的文件。

    FILE_ATTRIBUTE_SYSTEM4(0x4)操作系统使用其一部分或专门使用的文件或目录。

    FILE_ATTRIBUTE_TEMPORARY256(0x100)用于临时存储的文件。如果有足够的高速缓存可用,文件系统会避免将数据写回大容量存储器,因为通常,应用程序在句柄关闭后删除临时文件。在那种情况下,系统可以完全避免写入数据。否则,在句柄关闭后写入数据。

    FILETIME ftCreationTime;

    FILETIME结构。指定一个文件或目录的创建时间。如果文件系统不支持创建时间,此成员为0。

  2. FILETIME ftLastAccessTime;
    FILETIME结构。对于文件,指定文件最后被读取、写入,或(对于可执行文件)被运行的时间。对于目录,指定目录的创建时间。如果文件系统不支持最后一次写入时间,此成员为0。

  3. FILETIME ftLastWriteTime;
    FILETIME结构。对于文件,指定文件最后被写入、截短或重写的时间(例如调用WriteFile()或SetEndOfFile()时)。日期和时间在文件属性或描述符被改变时不会被更新。

  4. DWORD nFileSizeHigh;
    DWORD。文件大小(以字节为单位)的高DWORD。除非文件大小大于MAXDWORD,否则值为0。文件大小等于(nFileSizeHigh * (MAXDWORD + 1)) + nFileSizeLow。

  5. DWORD nFileSizeLow;
    DWORD。文件大小(以字节为单位)的低DWORD。

  6. DWORD dwReserved0;
    DWORD。如果dwFileAttributes成员含有FILE_ATTRIBUTE_REPARSE_POINT属性,这个成员指定重新分析点标签(reparse point tag)。否则这个值是未定义的。

•IO_REPARSE_TAG_CSV
•IO_REPARSE_TAG_DEDUP
•IO_REPARSE_TAG_DFS
•IO_REPARSE_TAG_DFSR
•IO_REPARSE_TAG_HSM
•IO_REPARSE_TAG_HSM2
•IO_REPARSE_TAG_MOUNT_POINT
•IO_REPARSE_TAG_NFS
•IO_REPARSE_TAG_RESERVED_ONE
•IO_REPARSE_TAG_RESERVED_RANGE
•IO_REPARSE_TAG_RESERVED_ZERO
•IO_REPARSE_TAG_SIS
•IO_REPARSE_TAG_SYMLINK
•IO_REPARSE_TAG_WIM

  1. DWORD dwReserved1;
    DWORD。保留给将来使用。

  2. Field_z WCHAR cFileName[MAX_PATH];
    CHAR/WCHAR数组,大小为MAX_PATH。文件名。

  3. Field_z WCHAR cAlternateFileName[14];
    CHAR/WCHAR数组,大小为14。文件的别名。名称的格式为8.3文件名格式

#ifdef _MAC
DWORD dwFileType;
DWORD dwCreatorType;
WORD wFinderFlags;
#endif
} WIN32_FIND_DATAW;

要查找文件,需要使用FindFirstFile()、FindNextFile()和FindClose()函数。

HANDLE WINAPI FindFirstFile(
    _In_ LPCTSTR        lpFileName,
    _Out_ LPWIN32_FIND_DATA    lpFindFileData
);

lpFileName
CHAR/WCHAR指针(取决于是否定义UNICODE)。路径或文件名。可以包含通配符,例如或?。不能以\字符结尾。如果以通配符、.字符或目录名结尾,用户必须有根目录和所有子目录的访问权限。(遍历目录中的所有文件时,应以.*结尾。)

lpFindFileData
WIN32_FIND_DATA指针。用于接收找到的文件/目录的信息。

返回值
如果成功,函数将创建一个搜索句柄,可以使用该句柄调用FindNextFile()和FindClose()。如果失败,返回INVALID_HANDLE_VALUE。

FindNextFile()函数

BOOL WINAPI FindNextFile(
    _In_ HANDLE        hFindFile,
    _Out_ LPWIN32_FIND_DATA    lpFindFileData
);

hFindFile
HANDLE。搜索句柄。

lpFindFileData
WIN32_FIND_DATA指针。用于接收找到的文件/目录的信息。

返回值
如果成功,返回TRUE;如果失败(例如找不到更多的文件了或其它原因),返回FALSE。

FindClose()函数

BOOL WINAPI FindClose(
    _Inout_ HANDLE hFindFile
);

释放搜索句柄。

hFindFile
HANDLE。搜索句柄。

返回值
如果成功,返回TRUE;如果失败,返回FALSE。

通配符(wildcards)
和?字符被用作通配符
格式为
.ext(ext为扩展名)。例如指定所有.txt文件:".txt"。指定D:\Projects\目录下所有.txt文件:"D:\Projects\.txt"。

指定全部具有某个名称的文件/目录
格式为name.(name为文件名)。例如指定所有名为readme(格式不限)的文件和目录:"readme."。指定D:\Projects\目录下的所有名为readme的文件:“D:\Projects\readme.*”。

指定具有一定长度的扩展名的文件
格式为name.???(name为文件名)。?的数量和扩展名长度一样。例如指定所有扩展名为4个字符,名为index的文件:“index.???”。

指定具有一定长度的文件名的文件
格式为???.ext(ext为扩展名)。?的数量和文件名的长度一样。例如指定所有扩展名为.txt,名字含有7个字符的文件:"???.txt"。

当前目录和上一级目录
调用FindFirstFile()时,使用".“表示当前目录,使用”…“表示上一级目录。FindFirstFile()和FindNextFile()所返回的文件/目录名也可能是”.“或”…",可以忽略。

  1. 遍历某个目录下的所有文件
#define _CRT_SECURE_NO_WARNINGS
#include<windows.h>
#include<iostream>
#include<string>
#include<comdef.h>
#include<vector>

using namespace std;
void listFiles(const char* dir);
vector<_bstr_t> F1, F2;

LPCTSTR transfrom(const char *dir)
{
	int num = MultiByteToWideChar(0, 0, dir, -1, NULL, 0);
	wchar_t *wide = new wchar_t[num];
	MultiByteToWideChar(0, 0, dir, -1, wide, num);
	return wide;
}


int main()
{
	char dir[100];
	cout << "Enter a directory (ends with \'\\\'): ";
	cin.getline( dir,100);
	strcat(dir, "*.*");
	//cout << dir << endl;
	listFiles(dir);


	return 0;
}

void listFiles(const char* dir)
{
	HANDLE hFind;
	WIN32_FIND_DATA findData;
	LARGE_INTEGER size;
	hFind = FindFirstFile(transfrom(dir), &findData);
	if (hFind == INVALID_HANDLE_VALUE)
	{
		cout << "Failed to find first file!\n";
		return;
	}
	do
	{
		// 忽略"."和".."两个结果 
		if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			_bstr_t Filename(findData.cFileName);
			cout << Filename << "\t<dir>\n";
			F1.push_back(Filename);
		}
		else
		{
			size.LowPart = findData.nFileSizeLow;
			size.HighPart = findData.nFileSizeHigh;
			_bstr_t Filename(findData.cFileName);
			//cout << Filename << "\t" << size.QuadPart << "bytes\n";
			F2.push_back(Filename);
		}
	} while (FindNextFile(hFind, &findData));

	vector<_bstr_t>::iterator it = F2.begin();
	for (it; it != F2.end(); ++it)
		cout << *it << endl;
	cout << "Done!\n";
}
  1. 遍历某个目录里的所有文件
#define _CRT_SECURE_NO_WARNINGS
#include<windows.h>
#include<iostream>
#include<string>
#include<comdef.h>
#include<vector>

using namespace std;
void listFiles(const char* dir);
vector<_bstr_t> F1, F2;
int total=0;
LPCTSTR transfrom(const char *dir)
{
	int num = MultiByteToWideChar(0, 0, dir, -1, NULL, 0);
	wchar_t *wide = new wchar_t[num];
	MultiByteToWideChar(0, 0, dir, -1, wide, num);
	return wide;
}


int main()
{
	char dir[100];
	cout << "Enter a directory (do not add \'\\\' in the end): ";
	cin.getline( dir,100);
	
	//cout << dir << endl;
	listFiles(dir);

	cout << total << endl;
	return 0;
}

void listFiles(const char* dir)
{
	HANDLE hFind;
	WIN32_FIND_DATA findData;
	LARGE_INTEGER size;
	char dirNew[1000];

	// 向目录加通配符,用于搜索第一个文件
	strcpy(dirNew, dir);
	strcat(dirNew, "\\*.*");
	//cout << dirNew << endl;
	hFind = FindFirstFile(transfrom(dirNew), &findData);
	if (hFind == INVALID_HANDLE_VALUE)
	{
		//cout << "Failed to find first file!\n";
		return;
	}
	do
	{
		_bstr_t Filename(findData.cFileName);
		//cout << Filename << endl;
		// 是否是文件夹,并且名称不为"."或".." 
		if (findData.dwFileAttributes && FILE_ATTRIBUTE_DIRECTORY!=0
			&& strcmp(Filename, ".") != 0
			&& strcmp(Filename, "..") != 0)
		{
			strcpy(dirNew, dir);
			strcat(dirNew, "\\");
			strcat(dirNew, Filename);
			F1.push_back(Filename);
			//cout << "dirNew = " << dirNew << endl;
			listFiles(dirNew);
			//cout << Filename << "\t<dir>\n";		
		}
		else
		{
			size.LowPart = findData.nFileSizeLow;
			size.HighPart = findData.nFileSizeHigh;
			//cout << Filename << "\t" << size.QuadPart << "bytes\n";
			F2.push_back(Filename);
		}
	} while (FindNextFile(hFind, &findData));
	FindClose(hFind);
	//vector<_bstr_t>::iterator it = F1.begin();
	//for (it; it != F1.end(); ++it)
	//	cout << *it << endl;
	total += F1.size();
	total += F2.size();
}

比较麻烦的就是先将char转成char*,然后又用char*转成LPCTSTR

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值