说明
用到的主要API:
- FindFirstFile()
- FindNextFile()
- FindClose()
用到的主要数据结构:
- WIN32_FIND_DATA
其用法自行查阅MSDN或其他地方, 有很多资料, 这里不再复述.
代码
DirectoryTraverser.h
#pragma once
#include <windows.h>
#ifndef __in
#define __in
#endif
#ifndef __out
#define __out
#endif
typedef void(*TraverseCallback)(const LPWIN32_FIND_DATA, void*);
class CDirectoryTraverser
{
public:
CDirectoryTraverser(__in TraverseCallback callback);
~CDirectoryTraverser();
private:
bool IsDirectory(__in const TCHAR*);
void RecurringTraverse(__in const TCHAR*);
TraverseCallback fTraverseCallback_;
void* p_user_data_;
TCHAR pts_type_[MAX_PATH];
public:
bool Traverse(__in const TCHAR*, __in void* p_user_data);
void SetType(__in const TCHAR*);
};
DirectoryTraverser.cpp
#include "DirectoryTraverser.h"
#include <iostream>
#include <tchar.h>
CDirectoryTraverser::CDirectoryTraverser(__in TraverseCallback callback)
: fTraverseCallback_(callback)
, p_user_data_(NULL)
{
int n = sizeof(pts_type_);
memset(pts_type_, 0, MAX_PATH);
}
CDirectoryTraverser::~CDirectoryTraverser()
{
}
bool CDirectoryTraverser::Traverse(__in const TCHAR* pts_path, __in void* p_user_data)
{
p_user_data_ = p_user_data;
if (!IsDirectory(pts_path))
return false;
RecurringTraverse(pts_path);
return true;
}
bool CDirectoryTraverser::IsDirectory(__in const TCHAR* pts_path)
{
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA wfd = { 0 };
hFind = FindFirstFile(pts_path, &wfd);
if (INVALID_HANDLE_VALUE == hFind)
return false;
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
return true;
else
return false;
}
void CDirectoryTraverser::RecurringTraverse(__in const TCHAR* pts_path)
{
if (pts_path == NULL)
return;
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA wfd = { 0 };
TCHAR pts_path_buf[MAX_PATH] = { 0 };
if (pts_type_[0] == 0)
_stprintf_s(pts_path_buf, MAX_PATH, _T("%s\\*"), pts_path);
else
_stprintf_s(pts_path_buf, MAX_PATH, _T("%s\\*.%s"), pts_path, pts_type_);
hFind = FindFirstFile(pts_path_buf, &wfd);
if (INVALID_HANDLE_VALUE == hFind)
return;
do
{
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (_tcscmp(wfd.cFileName, _T(".")) != 0
&& _tcscmp(wfd.cFileName, _T("..")) != 0)
RecurringTraverse(wfd.cFileName);
}
else if (fTraverseCallback_)
fTraverseCallback_(&wfd, p_user_data_);
else
break;
} while (FindNextFile(hFind, &wfd) != 0);
FindClose(hFind);
}
void CDirectoryTraverser::SetType(__in const TCHAR* str_type)
{
_tcscpy_s(pts_type_, MAX_PATH, str_type);
}
使用
// TEST_DirectoryTraverser.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "DirectoryTraverser.h"
static void TraverserDirectoryCallback(LPWIN32_FIND_DATA p_wfd, void* p_user_data)
{
_tprintf(_T("%s\r\n"), p_wfd->cFileName);
}
int _tmain(int argc, _TCHAR* argv[])
{
CDirectoryTraverser dt(TraverserDirectoryCallback);
dt.SetType(_T("ttf"));
bool b_result = dt.Traverse(_T("C:\\Windows\\Fonts"), NULL);
if (b_result)
_tprintf(_T("Traverse Successful\r\n"));
else
_tprintf(_T("Traverse Failed\r\n"));
_tsystem(_T("pause"));
return 0;
}