hwdir.cpp

来自「◆◆◆ 《投掷飞镖记分工具》◆◆◆ 操作系统 : Windows Mobil」· C++ 代码 · 共 347 行

CPP
347
字号
// HwDir.cpp: implementation of the CHwDir class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "PublicFunc.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

const TCHAR f_seps[]   = _T(";");

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CHwDir::CHwDir(
		LPCTSTR lpszBasePathOrFile,
		BOOL bSerachSubDir /*=TRUE*/,		// 搜索子目录
		BOOL bAbsolutePath /*=TRUE*/		// 是绝对路径
)
{
	m_pStrAryResFile = new CStringArray;
	if ( !m_pStrAryResFile ) return;
	m_pStrArySubDirectory_Private = new CStringArray;
	if ( !m_pStrArySubDirectory_Private ) return;
	m_pStrArySubDirectory = new CStringArray;
	if ( !m_pStrArySubDirectory ) return;

	//初始化变量
	TCHAR buf[MAX_PATH];
	m_bSerachSubDir = bSerachSubDir;
	m_bAbsolutePath = bAbsolutePath;
	m_pStrAryResFile->FreeExtra();
	m_pStrArySubDirectory_Private->FreeExtra();
	m_pStrArySubDirectory->FreeExtra();
	m_dwRelativePathStartPos = 0;
	ZeroMemory(m_szBasePathFile,sizeof(m_szBasePathFile));
	int iLen = 0;
	TCHAR *p = NULL;
	ZeroMemory(m_strFilter,sizeof(m_strFilter));
	m_AmountBytes = 0;
	iLen = _snprintf_hw((TCHAR*)m_szBasePathFile,LENGTH(m_szBasePathFile)-2*sizeof(TCHAR),_T("%s"),lpszBasePathOrFile);
	if ( iLen < 0 ) iLen = (int)lstrlen(m_szBasePathFile);


	//查找的是目录还是文件,取得目录名和过滤字符(*.*、*.exe、??.cpp等都是过滤条件)
	TCHAR TempBuf[MAX_PATH];
	ZeroMemory(TempBuf,sizeof(TempBuf));
	DWORD dwFileAttrib = GetFileAttributes(m_szBasePathFile);
	if((dwFileAttrib & FILE_ATTRIBUTE_DIRECTORY) && dwFileAttrib != 0xffffffff)	//指定搜索一个目录,没有过滤条件
	{
		lstrcpy(m_strFilter,_T("*.*"));
		if(m_szBasePathFile[iLen - 1] != _T('\\'))
			m_szBasePathFile[iLen] = _T('\\');
	}
	else	//指定了过滤条件
	{
		PartFileAndPathByFullPath(m_szBasePathFile,m_strFilter,sizeof(m_strFilter),TempBuf,sizeof(TempBuf));
		lstrcpyn( m_szBasePathFile, TempBuf, LENGTH(m_szBasePathFile) );
	}
	//找相对路径的位置
	if ( !bAbsolutePath )
	{
		lstrcpy((TCHAR*)buf,(const TCHAR*)m_szBasePathFile);
		if ( strchr_hw((const TCHAR*)buf,_T(':')) && (int)lstrlen((const TCHAR*)buf) == 3 )	//是诸如“E:\”、“d:\”的路径
		{
			m_dwRelativePathStartPos = 3;
		}
		else if ( (int)lstrlen((const TCHAR*)buf) == 1 && buf[0] == _T('\\'))			//是“\”,表示搜索当前盘的根目录
		{
			m_dwRelativePathStartPos = 1;
		}
		else																//一般目录(绝对路径、相对路径)
		{
			iLen = (int)lstrlen((const TCHAR*)buf);
			buf[iLen - 1] = _T('\0');
			p = strrchr_hw((const TCHAR*)buf,_T('\\'));
			if(p)
			{
				m_dwRelativePathStartPos = (DWORD)(p - buf + 1);
			}
		}
	}
	Dir();
}

CHwDir::~CHwDir()
{
	DELETE_ARRAY ( &m_pStrAryResFile );
	DELETE_ARRAY ( &m_pStrArySubDirectory_Private );
	DELETE_ARRAY ( &m_pStrArySubDirectory );
}
/********************************************************************************
* Function Type	:	private
* Parameter		:	None
* Return Value	:	获得的文件总数
* Description	:	将目录m_szBasePathFile下的所有文件列举出来
*********************************************************************************/
DWORD CHwDir::Dir()
{
	TCHAR strDirectory[MAX_PATH*4];
	DWORD dwLine = 0;
	FindDirAndFile(m_szBasePathFile);
	while ( m_bSerachSubDir )
	{
		dwLine = (DWORD)m_pStrArySubDirectory_Private->GetSize();
		if(dwLine < 1) break;
		//处理m_StrArySubDirectory中最后一个子目录
		_snprintf_hw((TCHAR*)strDirectory,LENGTH(strDirectory) - 1*sizeof(TCHAR),_T("%s"),m_pStrArySubDirectory_Private->GetAt(dwLine - 1));
		m_pStrArySubDirectory_Private->RemoveAt(dwLine - 1);
		FindDirAndFile(strDirectory);
	}
	return m_pStrAryResFile->GetSize();
}
/********************************************************************************
* Function Type	:	private
* Parameter		:	lpszDirectory		-	要搜索的纯目录
* Return Value	:	获得的文件总数
* Description	:	所有一个目录下的所有目录和符合过滤条件的文件
*********************************************************************************/
DWORD CHwDir::FindDirAndFile(LPCTSTR lpszDirectory)
{
	DWORD dwRet = 0;
	TCHAR strDirFile[MAX_PATH*2];
	_snprintf_hw((TCHAR*)strDirFile,LENGTH(strDirFile) - 1*sizeof(TCHAR),_T("%s*.*"),lpszDirectory);				//先搜索出子目录
	dwRet += FindAllFileUnderOneDir((LPCTSTR)strDirFile,lpszDirectory,TRUE);
	_snprintf_hw((TCHAR*)strDirFile,LENGTH(strDirFile) - 1*sizeof(TCHAR),_T("%s%s"),lpszDirectory,m_strFilter);	//再按过滤条件搜索
	dwRet += FindAllFileUnderOneDir(strDirFile,lpszDirectory,FALSE);
	return dwRet;
}
/********************************************************************************
* Function Type	:	private
* Parameter		:	lpszFileName		-	要处理的文件(这里把目录也视为文件)
*					lpszDirectory		-	纯目录(不需要再找目录了,减少计算量)
*					bFindDir			-	是否只搜索目录,不理会文件
* Return Value	:	获得的文件总数
* Description	:	查找lpszFileName指定的所有文件或所有目录
*********************************************************************************/
DWORD CHwDir::FindAllFileUnderOneDir(LPCTSTR lpszFileName,LPCTSTR lpszDirectory,BOOL bFindDir)
{
	DWORD dwFileNum = 0, dwDirNum = 0;
	WIN32_FIND_DATA FindData;
	HANDLE hFileHandle = FindFirstFile(lpszFileName,&FindData);
	if(hFileHandle == INVALID_HANDLE_VALUE)
		return dwFileNum;
	int iRet = HandleOneFile ( lpszDirectory, &FindData, bFindDir );
	if(iRet == 1)	//是文件
		dwFileNum ++;
	else if(iRet == 2)	//是目录
		dwDirNum ++;
	while ( FindNextFile ( hFileHandle, &FindData ) )
	{
		iRet = HandleOneFile ( lpszDirectory, &FindData, bFindDir );
		if(iRet == 1)	//是文件
			dwFileNum ++;
		else if(iRet == 2)	//是目录
			dwDirNum ++;
	}
	FindClose(hFileHandle);
	return dwFileNum;
}
/********************************************************************************
* Function Type	:	private
* Parameter		:	lpszDirectory		-	纯路径(不包含文件名)
*					pFindData			-	文件信息
*					bFindDir			-	TRUE  : 只搜索目录,不理会文件
*											FALSE : 只搜索文件,不理会目录
* Return Value	:	1					-	是一个有效的文件
*					2					-	是一个有效的目录
*					-1				_	-	不是想要的文件或目录
* Description	:	处理一个找到的文件(这里把目录也视为文件)
*********************************************************************************/
int CHwDir::HandleOneFile(LPCTSTR lpszDirectory, WIN32_FIND_DATA* pFindData,BOOL bFindDir)
{
	TCHAR ResBuf[3*MAX_PATH];
	ULONGLONG FileSize;
	LPDWORD pDword = (LPDWORD)&FileSize;
	pDword[0] = pFindData->nFileSizeLow;
	pDword[1] = pFindData->nFileSizeHigh;
	ZeroMemory(ResBuf,sizeof(ResBuf));
	if(lstrcmpi((LPCTSTR)pFindData->cFileName,_T(".."))== 0 || pFindData->cFileName[0] == _T('.'))
		return -1;
	if((pFindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && 
		pFindData->dwFileAttributes != 0xffffffff)
	{
		if(bFindDir)
		{
			_snprintf_hw((TCHAR*)ResBuf,LENGTH(ResBuf) - 1*sizeof(TCHAR),_T("%s%s\\"),lpszDirectory,pFindData->cFileName);
			m_pStrArySubDirectory_Private->Add((LPCTSTR)ResBuf);
			m_pStrArySubDirectory->Add((LPCTSTR)ResBuf);
			return 2;
		}
	}
	else if(!bFindDir)
	{
		_snprintf_hw((TCHAR*)ResBuf, LENGTH(ResBuf) - 1*sizeof(TCHAR),
			_T("%s%s"), lpszDirectory+m_dwRelativePathStartPos, pFindData->cFileName );
		m_pStrAryResFile->Add((LPCTSTR)ResBuf);
		m_AmountBytes += FileSize;
#ifdef _DEBUG
		TRACE(_T("NO.%04d : %s\t\t%d\t字节\n"),m_pStrAryResFile->GetSize(),ResBuf,FileSize);
#endif
		return 1;
	}
	return -1;
}

/********************************************************************************
* Function Type	:	public
* Parameter		:	None
* Return Value	:	None
* Description	:	取字节总数
*********************************************************************************/
ULONGLONG CHwDir::GetAmountBytes()
{
	return m_AmountBytes;
}

//////////////////////////////////////////////////////////////////////
// CHwDirEx Class
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CHwDirEx::CHwDirEx(
		LPCTSTR lpszMultiFindPath,					// 要搜索的多路径,如“E:\\winnt\\;d:\temp\\;”
		LPCTSTR lpszMultiFindFilter,				// 要搜索的过滤条件,如“*.bmp;*.exe;”
		LPCTSTR lpszMultiExcludeFilter/*=NULL*/,	// 要排除的过滤条件,如“*.bmp;*.exe;”
		BOOL bSerachSubDir/* = TRUE*/,				// 搜索子目录
		BOOL bAbsolutePath /*=TRUE*/				// 是绝对路径
)
	: m_AmountBytes ( 0 )
{
	ASSERT ( lpszMultiFindPath && (int)lstrlen(lpszMultiFindPath) > 0 );
	ASSERT ( lpszMultiFindFilter && (int)lstrlen(lpszMultiFindFilter) > 0 );

	m_pStrAryResFile = new CStringArray;
	if ( !m_pStrAryResFile ) return;
	m_pStrArySubDirectory = new CStringArray;
	if ( !m_pStrArySubDirectory ) return;

	CStringArray StrAryMultiFindPath;
	PartStringAndAddToStrAry ( (TCHAR*)lpszMultiFindPath, StrAryMultiFindPath, (TCHAR)f_seps[0] );
	for ( int i=0; i<StrAryMultiFindPath.GetSize(); i++ )
	{
		CString csFindPath = StrAryMultiFindPath.GetAt(i);
		DirAll ( csFindPath, lpszMultiFindFilter, lpszMultiExcludeFilter, bSerachSubDir, bAbsolutePath );
	}
}

CHwDirEx::~CHwDirEx()
{
	DELETE_ARRAY ( &m_pStrAryResFile );
	DELETE_ARRAY ( &m_pStrArySubDirectory );
}

ULONGLONG CHwDirEx::GetAmountBytes()
{
	return m_AmountBytes;
}

void CHwDirEx::DirAll(
		LPCTSTR lpszFindPath,						// 要搜索的路径,如“E:\\winnt\\”
		LPCTSTR lpszMultiFindFilter,				// 要搜索的过滤条件,如“*.bmp;*.exe;”
		LPCTSTR lpszMultiExcludeFilter/*=NULL*/,	// 要排除的过滤条件,如“*.bmp;*.exe;”
		BOOL bSerachSubDir/* = TRUE*/,				// 搜索子目录
		BOOL bAbsolutePath /*=TRUE*/				// 是绝对路径
)
{
	ASSERT ( lpszFindPath && (int)lstrlen(lpszFindPath) > 0 );

	CStringArray	StrAryResFile_Find, StrAryResFile_Exclude,
					StrArySubDirectory_Find, StrArySubDirectory_Exclude;
	DWORD			dwAmountBytes_Find = 0, dwAmountBytes_Exclude = 0;

	// 先搜索符合指定过滤条件的文件
	Dir ( lpszFindPath, lpszMultiFindFilter, StrAryResFile_Find, StrArySubDirectory_Find,
		dwAmountBytes_Find,	bSerachSubDir, bAbsolutePath );

	// 再搜索需要排除的文件
	if ( lpszMultiExcludeFilter && (int)lstrlen ( lpszMultiExcludeFilter ) > 0 )
	{
		ASSERT ( lpszMultiExcludeFilter && (int)lstrlen(lpszMultiExcludeFilter) > 0 );
		Dir ( lpszFindPath, lpszMultiExcludeFilter, StrAryResFile_Exclude, StrArySubDirectory_Exclude,
			dwAmountBytes_Exclude, bSerachSubDir, bAbsolutePath );
		// 然后从 StrAryResFile_Find 中删除掉需要排除的文件
		for ( int i=0; i<StrAryResFile_Exclude.GetSize(); i++ )
		{
			CString csResFile = StrAryResFile_Exclude.GetAt(i);
			int nFindPos = FindFromArray ( StrAryResFile_Find, csResFile );
			if ( nFindPos >= 0 ) StrAryResFile_Find.RemoveAt ( nFindPos );
		}
	}

	// 最后将搜索结果保存到成员变量中,并清理临时变量
	m_pStrAryResFile->Append ( StrAryResFile_Find );
	m_pStrArySubDirectory->Append ( StrArySubDirectory_Find );
	m_AmountBytes += (dwAmountBytes_Find - dwAmountBytes_Exclude);
	StrAryResFile_Find.RemoveAll();
	StrAryResFile_Exclude.RemoveAll();
	StrArySubDirectory_Find.RemoveAll();
	StrArySubDirectory_Exclude.RemoveAll();
}

void CHwDirEx::Dir(
		LPCTSTR lpszFindPath,						// 要搜索的路径,如“E:\\winnt\\”
		LPCTSTR lpszMultiFindFilter,				// 要搜索的过滤条件,如“*.bmp;*.exe;”
		CStringArray &StrAryResFile,				// 搜索的文件保存到此
		CStringArray &StrArySubDirectory,			// 搜索的子目录保存到此
		DWORD &dwAmountBytes,						// 总字节数保存到此
		BOOL bSerachSubDir/* = TRUE*/,				// 搜索子目录
		BOOL bAbsolutePath /*=TRUE*/				// 是绝对路径
)
{
	ASSERT ( lpszFindPath && (int)lstrlen(lpszFindPath) > 0 );
	dwAmountBytes = 0;
	StrAryResFile.RemoveAll();
	StrArySubDirectory.RemoveAll();

	TCHAR szFindPath[MAX_PATH] = {0}, szMultiFindFilter[10240]={0}, szMultiExcludeFilter[1024]={0};
	lstrcpyn ( szFindPath, lpszFindPath, LENGTH(szFindPath) );
	lstrcpyn ( szMultiFindFilter, lpszMultiFindFilter, LENGTH(szMultiFindFilter) );
	StandardizationPathBuffer ( szFindPath, sizeof(szFindPath), _T('\\') );

	TCHAR *token = strtok_hw( szMultiFindFilter, f_seps );
	while( token != NULL )
	{
		/* While there are tokens in _T("string") */
		TCHAR szFindFile[MAX_PATH] = {0};
		_snprintf_hw ( szFindFile, LENGTH(szFindFile)-1*sizeof(TCHAR), _T("%s%s"), szFindPath, token );
		CHwDir dir ( szFindFile, bSerachSubDir, bAbsolutePath );
		if ( dir.m_pStrAryResFile && dir.m_pStrArySubDirectory )
		{
			StrAryResFile.Append ( *(dir.m_pStrAryResFile) );
			StrArySubDirectory.Append ( *(dir.m_pStrArySubDirectory) );
			dwAmountBytes += (DWORD)dir.GetAmountBytes();
		}
		/* Get next token: */
		token = strtok_hw( NULL, f_seps );
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?