#include "stdafx.h"
#include "FileFindAll.h"
#include <stdlib.h>
#include <time.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
static int FileInfo_compare( const void *arg1, const void *arg2 )
{
FileInfo *F1 = (FileInfo *) arg1;
FileInfo *F2 = (FileInfo *) arg2;
return _stricmp(F1->Name, F2->Name);
}
CFileFindAll::CFileFindAll()
{
Close();
}
CFileFindAll::~CFileFindAll()
{
Close();
}
CString CFileFindAll::GetFileName() const
{
if(b_FileFound) return m_strFileName;
else return _T("");
}
CString CFileFindAll::GetFilePath() const
{
if(b_FileFound) return m_strFilePath;
else return _T("");
}
CString CFileFindAll::GetFileTitle() const
{
if(b_FileFound) return m_strFileTitle;
else return _T("");
}
CString CFileFindAll::GetFileURL() const
{
if(b_FileFound) return m_strFileURL;
else return _T("");
}
CString CFileFindAll::GetRoot() const
{
if(b_FileFound) return m_strFileRoot;
else return _T("");
}
CString CFileFindAll::GetRoot(int &nLevel) const
{
if(b_FileFound)
{
int nLevelTotal = 0;
CString strPathTotal = m_strFileRoot;
int nStart = 0;
while (nStart!=-1)
{
nStart = strPathTotal.Find('\\',nStart+1);
nLevelTotal++;
}
if(nLevel==0)
{
nLevel = nLevelTotal;
return strPathTotal;
}
if(nLevel>0)
{
if(nLevel>=nLevelTotal)
{
nLevel = nLevelTotal;
return strPathTotal;
}
nStart=0;
while (nLevel!=0)
{
nStart = strPathTotal.Find('\\',nStart+1);
nLevel--;
}
strPathTotal = strPathTotal.Left(nStart);
nLevel = nLevelTotal;
return strPathTotal;
}
if(nLevel<0)
{
if(-nLevel>=nLevelTotal) nLevel = 1;
else nLevel += nLevelTotal;
nStart=0;
while (nLevel!=0)
{
nStart = strPathTotal.Find('\\',nStart+1);
nLevel--;
}
strPathTotal = strPathTotal.Left(nStart);
nLevel = nLevelTotal;
return strPathTotal;
}
}
else return _T("");
}
void CFileFindAll::Close()
{
while(!DirStack.empty()) DirStack.pop();
while(!FileStack.empty()) FileStack.pop();
m_strExt = _T("");
b_FileFound = FALSE;
m_SortMode = modeNorm;
}
BOOL CFileFindAll::FindFile(LPCTSTR pstrDir, LPCTSTR pstrExt)
{
if(!DirStack.empty() || !FileStack.empty()) Close();
CString strTemp(pstrExt);
m_strExt = strTemp;
CString strCurFolder = _T("");
DirStack.push(pstrDir);
if (m_SortMode == modeRandAll)
{
while(!DirStack.empty())
{
strCurFolder=DirStack.top();
DirStack.pop();
if(FindInFolder(strCurFolder,m_strExt));
while (!FileStack.empty())
{
vFilesInFolder.push_back(FileStack.top());
FileStack.pop();
}
}
srand( (unsigned)time( NULL ) );
double lfRandom = rand();
int nIndex;
int i = vFilesInFolder.size();
// CString msg;
// msg.Format("Totally %d files!",i);
// AfxMessageBox(msg);
for (; i > 0; i--)
{
lfRandom = rand();
nIndex = lfRandom / (double)RAND_MAX * (double)i;
if(nIndex>=i) nIndex = i-1;
else if (nIndex < 0) nIndex = 0;
FileStack.push(vFilesInFolder[nIndex]);
vFilesInFolder.erase(vFilesInFolder.begin() + nIndex);
}
vFilesInFolder.clear();
if(!FileStack.empty()) return TRUE;
}
while(!DirStack.empty())
{
strCurFolder=DirStack.top();
DirStack.pop();
if(FindInFolder(strCurFolder,m_strExt)) return TRUE;
}
return FALSE;
}
BOOL CFileFindAll::FindFile(LPCTSTR pstrName, SortMode mode)
{
CString strName (pstrName );
CString strDir;
CString strExt;
m_SortMode = mode;
int nIndex = -1;
nIndex = strName.ReverseFind('\\');
if(nIndex == -1) return FALSE;
strDir = strName.Left(nIndex);
nIndex = strName.GetLength() - nIndex - 1;
strExt = strName.Right(nIndex);
return FindFile(strDir,strExt);
}
BOOL CFileFindAll::FindNextFile()
{
FileInfo CurFile;
if(!FileStack.empty())
{
CurFile = FileStack.top();
FileStack.pop();
b_FileFound = TRUE;
m_strFileName = CurFile.Name ;
m_strFilePath = CurFile.Path ;
m_strFileTitle = CurFile.Title;
m_strFileURL = CurFile.URL ;
m_strFileRoot = CurFile.Root ;
if(!FileStack.empty()) return TRUE;
else while(!DirStack.empty())
{
CString strCurFolder = _T("");
strCurFolder=DirStack.top();
DirStack.pop();
if(FindInFolder(strCurFolder,m_strExt)) return TRUE;
}
}
return FALSE;
}
BOOL CFileFindAll::FindInFolder(LPCTSTR pstrDir, LPCTSTR pstrExt)
{
CString filepath = _T("");
CString filename = _T("");
FileInfo CurFile;
CString strDir(pstrDir);
b_FileFound = FALSE;
BOOL bFound;
CFileFind finder;
bFound=finder.FindFile(strDir+"\\*.*");
while(bFound)
{
bFound =finder.FindNextFile();
filepath=finder.GetFilePath();
filename=finder.GetFileName();
if(finder.IsDirectory())//是目录,入栈
{
if( filename!="." && filename!="..")
DirStack.push(filepath);
}
else if(MatchExt(filename,m_strExt))//是文件,如果扩展名匹配则入栈
{
CurFile.Name = finder.GetFileName();
CurFile.Path = finder.GetFilePath();
CurFile.Title = finder.GetFileTitle();
CurFile.URL = finder.GetFileURL();
CurFile.Root = finder.GetRoot();
FileStack.push(CurFile);
b_FileFound = TRUE;
}
}
if(b_FileFound)
{
if (m_SortMode == modeNorm) return TRUE;
if (m_SortMode == modeSort)
{
while (!FileStack.empty())
{
vFilesInFolder.push_back(FileStack.top());
FileStack.pop();
}
qsort((void *)&(vFilesInFolder[0]), vFilesInFolder.size(),
sizeof( FileInfo ), FileInfo_compare);
for (int i= vFilesInFolder.size() - 1; i>=0; i--)
FileStack.push(vFilesInFolder[i]);
vFilesInFolder.clear();
return TRUE;
}
if (m_SortMode == modeRand)
{
while (!FileStack.empty())
{
vFilesInFolder.push_back(FileStack.top());
FileStack.pop();
}
srand( (unsigned)time( NULL ) );
double lfRandom = rand();
int nIndex;
for (int i = vFilesInFolder.size(); i > 0; i--)
{
lfRandom = rand();
nIndex = lfRandom / (double)RAND_MAX * (double)i;
if(nIndex>=i) nIndex = i-1;
else if (nIndex < 0) nIndex = 0;
FileStack.push(vFilesInFolder[nIndex]);
vFilesInFolder.erase(vFilesInFolder.begin() + nIndex);
}
vFilesInFolder.clear();
}
return TRUE;
}
else return FALSE;
}
BOOL CFileFindAll::MatchExt(LPCTSTR pstrName, LPCTSTR pstrExt)
{
CString strName(pstrName);
CString strExt (pstrExt );
int nIndex = -1;
nIndex = strExt.ReverseFind('.');
if(nIndex == -1) return FALSE;
nIndex = strExt.GetLength() - nIndex - 1;
strExt = strExt.Right(nIndex);
if (!strExt.Compare("*")) return TRUE;
strExt.MakeLower();
nIndex = strName.ReverseFind('.');
if(nIndex == -1) return FALSE;
nIndex = strName.GetLength() - nIndex - 1;
strName = strName.Right(nIndex);
strName.MakeLower();
if(!strcmp(strName,strExt)) return TRUE;
else return FALSE;
}