Ultimately I want to travel through a folder's files and subdirectories and write something to all files i find that have a certain extension(.wav in my case). when looping how do i tell if the item I am at is a directory?
问题:
回答1:
Here is how you do it (this is all from memory so there may be errors):
void FindFilesRecursively(LPCTSTR lpFolder, LPCTSTR lpFilePattern)
{
TCHAR szFullPattern[MAX_PATH];
WIN32_FIND_DATA FindFileData;
HANDLE hFindFile;
// first we are going to process any subdirectories
PathCombine(szFullPattern, lpFolder, _T("*"));
hFindFile = FindFirstFile(szFullPattern, &FindFileData);
if(hFindFile != INVALID_HANDLE_VALUE)
{
do
{
if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// found a subdirectory; recurse into it
PathCombine(szFullPattern, lpFolder, FindFileData.cFileName);
FindFilesRecursively(szFullPattern, lpFilePattern);
}
} while(FindNextFile(hFindFile, &FindFileData));
FindClose(hFindFile);
}
// Now we are going to look for the matching files
PathCombine(szFullPattern, lpFolder, lpFilePattern);
hFindFile = FindFirstFile(szFullPattern, &FindFileData);
if(hFindFile != INVALID_HANDLE_VALUE)
{
do
{
if(!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
// found a file; do something with it
PathCombine(szFullPattern, lpFolder, FindFileData.cFileName);
_tprintf_s(_T("%s\n"), szFullPattern);
}
} while(FindNextFile(hFindFile, &FindFileData));
FindClose(hFindFile);
}
}
So you could call this like
FindFilesRecursively(_T("C:\\WINDOWS"), _T("*.wav"));
to find all the *.wav files in C:\WINDOWS and its subdirectories.
Technically you don't have to do two FindFirstFile() calls, but I find the pattern matching functions Microsoft provides (i.e. PathMatchFileSpec or whatever) aren't as capable as FindFirstFile(). Though for "*.wav" it would probably be fine.
回答2:
Based on your mention of .wav
, I'm going to guess you're writing code for Windows (that seems to be where *.wav
files are most common). In this case, you use FindFirstFile
and FindNextFile
to traverse directories. These use a WIN32_FIND_DATA
structure, which has a member dwFileAttributes
that contains flags telling the attributes of the file. If dwAttributes & FILE_ATTRIBUTE_DIRECTORY
is non-zero, you have the name of a directory.
回答3:
Very Helpful. I had anyway, a stack overflow since it was always adding "." to the path and returning to the same path = endless loop.
Adding this solved it:
// found a subdirectory; recurse into it
PathCombine(szFullPattern, lpFolder, FindFileData.cFileName);
FindFilesRecursively(szFullPattern, lpPattern);
if (FindFileData.cFileName[0] == '.') continue;
回答4:
opendir and readdir (on unix), here's an example:
http://opengroup.org/onlinepubs/007908775/xsh/readdir.html
or FindFirstFile on windows
you could also use the shell pretty easily:
find . -name "*.wav"
or
ls **/*.wav (in zsh and newer bashes)
回答5:
check these links
- http://msdn.microsoft.com/en-us/library/aa365522(VS.85).aspx
- http://www.codeguru.com/forum/showthread.php?t=312461