c++ - 对于以 "."(例如 : ".NET"))开头的目录,文件列表失败

标签 c++ winapi

<分区>

我正在尝试列出目录中的所有文件。问题是它不断跳过目录“.NET”下的一些文件。基本上它会跳过目录名下以“.”开头的所有文件。可能的原因是什么?

#include "stdafx.h"
#include <windows.h>
#include <string>
#include <iostream>
#include <list>
#include <fstream>

using namespace std;
void addFileToList(list<string>& fileList,const string& directory,const string& excludeFilter,const WIN32_FIND_DATA &FindFileData)
{
    string fileName = string(FindFileData.cFileName);
    string filePath = directory + fileName;

    if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) 
    {
        string fileExtension = fileName.substr(fileName.find_last_of(".") + 1);
        if (fileExtension.empty()) 
        {
            fileList.push_back(filePath);
            return;
        } 
        else if ( ( excludeFilter.find(fileExtension) == string::npos ) )
        {
            fileList.push_back(filePath);
        }
    }
}

void GetFileListing(list<string>& fileList, string directory,const string& excludeFilter,bool recursively=true)
{
    string filePath,fileName,fileExtension;
    if (recursively)
    {
        GetFileListing(fileList, directory, excludeFilter,false);
    }

    WIN32_FIND_DATA FindFileData;
    HANDLE hFind = INVALID_HANDLE_VALUE;

    directory += "\\";
    string filter = directory + "*";

    // Find the first file in the directory.
    hFind = FindFirstFile(filter.c_str(), &FindFileData);

    if (hFind == INVALID_HANDLE_VALUE)
    {
        DWORD dwError = GetLastError();
        if (dwError!=ERROR_FILE_NOT_FOUND)
        {
            //cout << "Invalid file handle for filter "<<filter<<". Error is " << GetLastError() << endl;
        }
    }
    else
    {
        // Add the first file found to the list
        if (!recursively)
        {
            addFileToList(fileList,directory,excludeFilter,FindFileData);
        }

        // List all the other files in the directory.
        while (FindNextFile(hFind, &FindFileData) != 0)
        {
            if (!recursively)
            {
                addFileToList(fileList,directory,excludeFilter,FindFileData);
            }
            else
            {
                // If we found a directory then recurse into it
                if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && FindFileData.cFileName[0]!='.')
                {
                    GetFileListing(fileList, directory + string(FindFileData.cFileName),excludeFilter);
                }
            }
        }

        DWORD dwError = GetLastError();
        FindClose(hFind);
        if (dwError != ERROR_NO_MORE_FILES)
        {
            //cout << "FindNextFile error. Error is "<< dwError << endl;
        }
    }
}


int _tmain(int argc, _TCHAR* argv[])
{
    list<string> fileList;
    list<string>::iterator it;
    string excludeFilter;
    string directory=".";
    GetFileListing(fileList, directory,excludeFilter);

    for( it=fileList.begin(); it!=fileList.end();++it) 
    {
        cout<<(*it)<<endl;
    }

    return 0;
}

更新代码:

根据 Hans 的建议,我添加了对目录的检查。现在可以了!有什么建议吗?

#include "stdafx.h"
#include <windows.h>
#include <string>
#include <iostream>
#include <list>
#include <fstream>

using namespace std;

void addFileToList( list<string>& fileList,const string& directory,const string& excludeFilter,const string &fileName )
{
    string filePath = directory + fileName;
    string fileExtension = fileName.substr(fileName.find_last_of(".") + 1);

    if (fileExtension.empty()) 
    {
        fileList.push_back(filePath);
        return;
    } 
    else if ( ( excludeFilter.find(fileExtension) == string::npos ) )
    {
        fileList.push_back(filePath);
    }
}

void GetFileListing(list<string>& fileList, string directory,const string& excludeFilter,bool recursively=true)
{
    // 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

    string filePath,fileName,fileExtension;
    if (recursively)
    {
        GetFileListing(fileList, directory, excludeFilter,false);
    }

    WIN32_FIND_DATA FindFileData;
    HANDLE hFind = INVALID_HANDLE_VALUE;

    directory += "\\";
    string filter = directory + "*";

    // Find the first file in the directory.
    hFind = FindFirstFile(filter.c_str(), &FindFileData);

    if (hFind == INVALID_HANDLE_VALUE)
    {
        DWORD dwError = GetLastError();
        if (dwError!=ERROR_FILE_NOT_FOUND)
        {
            //cout << "Invalid file handle for filter "<<filter<<". Error is " << GetLastError() << endl;
        }
    }
    else
    {
        // Add the first file found to the list
        if (!recursively)
        {
            if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
            {
                string fileName = string(FindFileData.cFileName);
                addFileToList(fileList,directory,excludeFilter,fileName);
            } 
        }

        if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
        {
            // List all the other files in the directory.
            while (FindNextFile(hFind, &FindFileData) != 0)
            {
                if (!recursively)
                {
                    if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
                    {
                        string fileName = string(FindFileData.cFileName);
                        addFileToList(fileList,directory,excludeFilter,fileName);
                    } 
                    else 
                    {
                        if ( string(FindFileData.cFileName)=="." || string(FindFileData.cFileName)==".." ) continue;
                        GetFileListing(fileList, directory + string(FindFileData.cFileName),excludeFilter);
                    }
                }
            }
        }

        DWORD dwError = GetLastError();
        FindClose(hFind);
        if (dwError != ERROR_NO_MORE_FILES)
        {
            //cout << "FindNextFile error. Error is "<< dwError << endl;
        }
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    list<string> fileList;
    list<string>::iterator it;
    string excludeFilter;
    string directory=".";
    GetFileListing(fileList, directory,excludeFilter);

    for( it=fileList.begin(); it!=fileList.end();++it) 
    {
        cout<<(*it)<<endl;
    }

    return 0;
}

最佳答案

试试这个:

#include "stdafx.h"
#include <windows.h>
#include <string>
#include <iostream>
#include <list>
#include <fstream>

using namespace std;

void addFileToList(list<string>& fileList, const string& directory, const string& fileName, const string& excludeFilter)
{
    string fileExtension = fileName.substr(fileName.find_last_of(".") + 1);
    if (!fileExtension.empty()) 
    {
        if (excludeFilter.find(fileExtension) != string::npos)
            return;
    } 

    fileList.push_back(directory + fileName);
}

void GetFileListing(list<string>& fileList, string directory, const string& excludeFilter, bool recursively = true)
{
    string filePath;

    directory += "\\";
    string filter = directory + "*";

    WIN32_FIND_DATA FindFileData;
    HANDLE hFind = FindFirstFile(filter.c_str(), &FindFileData);

    if (hFind == INVALID_HANDLE_VALUE)
    {
        DWORD dwError = GetLastError();
        if (dwError != ERROR_FILE_NOT_FOUND)
        {
            //cout << "Invalid file handle for filter " << filter << ". Error is " << GetLastError() << endl;
        }
        return;
    }

    do
    {
        if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
        {
            if ((recursively) && (lstrcmp(FindFileData.cFileName, TEXT(".")) != 0) && (lstrcmp(FindFileData.cFileName, TEXT("..")) != 0))
                GetFileListing(fileList, directory + FindFileData.cFileName, excludeFilter);
        }
        else
            addFileToList(fileList, directory, FindFileData.cFileName, excludeFilter);
    }
    while (FindNextFile(hFind, &FindFileData) != 0);

    DWORD dwError = GetLastError();
    FindClose(hFind);

    if (dwError != ERROR_NO_MORE_FILES)
    {
        //cout << "FindNextFile error. Error is "<< dwError << endl;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    list<string> fileList;
    GetFileListing(fileList, ".", "");

    for(list<string>::iterator it = fileList.begin(); it != fileList.end(); ++it) 
    {
        cout << (*it) << endl;
    }

    return 0;
}

关于c++ - 对于以 "."(例如 : ".NET"))开头的目录,文件列表失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14473169/

相关文章:

c - 在没有MFC的情况下使用MFC库

c++ - 高效可靠的 SID/PSID 散列

c++ - 如果 stdin 被另一个进程的管道替换,则 std::getline 中断

c++ - 为什么我的 TicTacToe 游戏在生成随机移动时会卡住

c++ - 从二进制文件中读取 Int

C++ spirit boost : Making a input iterator into a forward iterator

winapi - 如何加载与 Windows 10 上 MessageBox 使用的相同图标?

C++ 数组,我应该如何修复我的数组,它需要删除变量的所有倍数?

C++ 编译器错误

c++ - 从新分配更改为智能指针后出现堆错误