我想得到特定目录中所有文件的列表。为此|我使用以下代码
void GetFileListing(std::list<std::string>& listing, std::string directory, std::string fileFilter, bool recursively=true)
{
//check if directory exits:
DWORD attribs = ::GetFileAttributesA(directory.c_str());
if (attribs == INVALID_FILE_ATTRIBUTES || !(attribs & FILE_ATTRIBUTE_DIRECTORY)) {
return ;
}
// If we are going to recurse over all the subdirectories, first of all
// get all the files that are in this directory that match the filter
if (recursively)
GetFileListing(listing, directory, fileFilter, false);
directory += "\\";
WIN32_FIND_DATA FindFileData;
HANDLE hFind = INVALID_HANDLE_VALUE;
// Setup the filter according to whether we are getting the directories
// or just the files
std::string filter = directory + (recursively ? "*" : fileFilter);
// Find the first file in the directory.
hFind = FindFirstFile(LPCWSTR(filter.c_str()), &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
DWORD dwError = GetLastError();
if (dwError!=ERROR_FILE_NOT_FOUND)
{
std::cout << "Invalid file handle for filter "<<filter<<". Error is " << GetLastError() << std::endl;
}
}
else
{
// Add the first file found to the list
if (!recursively)
{
wstring wFindFileData = FindFileData.cFileName;
listing.push_back(directory + std::string(wFindFileData.begin(),wFindFileData.end()));
}
// List all the other files in the directory.
while (FindNextFile(hFind, &FindFileData) != 0)
{
if (!recursively)
{
wstring wFindFileData = FindFileData.cFileName;
listing.push_back(directory + std::string(wFindFileData.begin(),wFindFileData.end()));
}
else
{
// If we found a directory then recurse into it
if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)>0 && FindFileData.cFileName[0]!='.')
{
wstring wFindFileData = FindFileData.cFileName;
GetFileListing(listing, directory + std::string(wFindFileData.begin(),wFindFileData.end()), fileFilter);
}
}
}
DWORD dwError = GetLastError();
FindClose(hFind);
if (dwError != ERROR_NO_MORE_FILES)
{
std::cout << "FindNextFile error. Error is "<< dwError << std::endl;
}
}
}
int main(int argc, char *argv[])
{
if(argc < 2)
return 0;
std::list<std::string> listing;
GetFileListing(listing, argv[1], "*");
for(std::list<std::string>::iterator it = listing.begin(); it!=listing.end();++it)
{
std::cout << *it << std::endl;
}
}
在args中我传输一个有效的现有目录.Actualy args [1]变为“C:\ dir”。 但是我没有得到所需的列表,而是发生以下错误:
Invalid file handle for filter C:\dir\*. Error is 123
我不明白这里有什么问题?
答案 0 :(得分:2)
您将ANSI与UNICODE混合使用,更糟糕的是,将char*
转换为wchar_t*
。
std::string filter;
// ...
LPCWSTR(filter.c_str()) // this does not work and causes the error!
如果您要求您的功能使用std::string
,请将其完全保留为ANSI(使用FindFirstFileA
,FindNextFileA
和WIN32_FIND_DATAA
)。
否则,请使用std::wstring
,并使用以W
结尾的函数/结构,而不是A
。
如果定义FindFirstFile
,则Windows标头将FindFirstFileW
定义为UNICODE
,否则定义FindFirstFileA
。因此,对于通用解决方案,请键入一个std::basic_string<TCHAR>
并将其用作字符串类型。这样它在定义UNICODE
时使用std :: wstring,否则使用std :: string。