【问题标题】:File count in a directory using C++使用 C++ 的目录中的文件计数
【发布时间】:2011-02-17 15:12:47
【问题描述】:

如何使用 C++ 标准库获取目录中的文件总数? 任何帮助表示赞赏。

【问题讨论】:

  • 不幸的是,目录操作与您所在的操作系统相关。所以发布您正在尝试的操作系统,也许我们可以更好地帮助您。
  • 跨平台代码可在 Windows 和 Linux 上运行。我正在使用 mingw、gcc 和 msvc 以及 wxWidgets 库,使用 boost 但不链接到它的库,只包括标题。我们在#include 中有 fstat 和 _stat 函数。获取文件详细信息。我们对获取目录详细信息有类似的支持吗?

标签: c++


【解决方案1】:

你不能。你能得到的最接近的是使用Boost.Filesystem

【讨论】:

  • 之后就很简单了:int count = std::difference(directory_iterator(dir_path), directory_iterator());
  • @MSalters,我找不到对std::difference 的任何引用。你确定你说的不是std::distance?此外,您需要static_cast<int>directory_iterator::difference_type 强制转换为int
  • 我正在尝试避免链接到 Boost 库,并且仅将标头用于算法。
  • 我们是否有办法避免链接到 Boost 文件系统库并仍然获得对此的支持?
  • @Nathan:当然。 @harik:不起作用;您需要的代码在 Boost 库中。
【解决方案2】:

您需要使用本机 API 或框架。

【讨论】:

    【解决方案3】:

    如果您不排除基本始终可用的 C 标准库,则可以使用该标准库。 因为它在任何地方都可用,与 boost 不同,它是一个非常有用的选项!

    举个例子here

    这里:

    #include <stdio.h>
    #include <sys/types.h>
    #include <dirent.h>
    
    int main (void)
    {
      DIR *dp;
      int i = 0;
      struct dirent *ep;     
      dp = opendir ("./");
    
      if (dp != NULL)
      {
        while (ep = readdir (dp))
          i++;
    
        (void) closedir (dp);
      }
      else
        perror ("Couldn't open the directory");
    
      printf("There's %d files in the current directory.\n", i);
    
      return 0;
    }
    

    果然

     > $ ls -a | wc -l
    138
     > $ ./count
    There's 138 files in the current directory.
    

    这根本不是 C++,但它适用于大多数(如果不是全部)操作系统,并且无论如何都可以在 C++ 中工作。

    更新:我将更正我之前关于这是 C 标准库的一部分的声明 - 它不是。但是您可以将此概念应用到其他操作系统,因为它们都有自己处理文件的方式,而无需使用额外的库。

    编辑::添加了 i 的初始化

    【讨论】:

    • -1:C 标准库也没有提供枚举目录的方法。
    • 那是愚蠢的反对票。当然,您可以使用 C 标准库对文件进行计数。以我在帖子中包含的示例为例——不要在用于迭代每个文件的 while 中调用“puts ...”,只需执行“i++”并在上方某处声明一个“int i”。当然没有“directory_get_file_count”函数,但这不是重点。关键是,您可以使用它来获得所需的结果,即文件夹中的文件数量。见鬼,让我用勺子喂的答案编辑我的原始答案,秒
    • 对于 readdir 的 POSIX 部分,这是真的,但是在 windows 中你有类似的功能,我无法在这里测试,因为我已经很久没有使用 windows。但关键是:这适用于 C++,这适用于 C,您不需要安装特殊的库支持,这可能是 OP 想要的。
    • @LukeN:POSIX “特殊库支持”。 Windows 没有&lt;sys/types.h&gt;,也没有&lt;dirent.h&gt;。 POSIX 不是 C 标准库,您断言它是错误的。
    • 基本上您现在已经看到 Daniel 最初的评论:“只使用本机 OS 函数,而不是(标准)库”。
    【解决方案4】:

    如果它们的名称、排序良好且具有相同的扩展名,您可以简单地使用标准 C++ 库对它们进行计数。

    假设文件名类似于“img_0.jpg..img_10000.jpg..img_n.jpg”, 只需检查它们是否在文件夹中。

    int Trainer::fileCounter(string dir, string prefix, string extension)
    {
        int returnedCount = 0;
        int possibleMax = 5000000; //some number you can expect.
    
        for (int istarter = 0; istarter < possibleMax; istarter++){
            string fileName = "";
            fileName.append(dir);
            fileName.append(prefix);
            fileName.append(to_string(istarter));
            fileName.append(extension);
            bool status = FileExistenceCheck(fileName);
    
            returnedCount = istarter;
    
            if (!status)
                break;
        }
    
        return returnedCount;
    }
    
    bool Trainer::FileExistenceCheck(const std::string& name) {
        struct stat buffer;
        return (stat(name.c_str(), &buffer) == 0);
    }
    

    【讨论】:

      【解决方案5】:

      一个老问题,但由于它首先出现在 Google 搜索中,所以我想添加我的答案,因为我需要类似的东西。

      int findNumberOfFilesInDirectory(std::string& path)
      {
          int counter = 0;
          WIN32_FIND_DATA ffd;
          HANDLE hFind = INVALID_HANDLE_VALUE;
      
          // Start iterating over the files in the path directory.
          hFind = ::FindFirstFileA (path.c_str(), &ffd);
          if (hFind != INVALID_HANDLE_VALUE)
          {
              do // Managed to locate and create an handle to that folder.
              { 
                  counter++;
              } while (::FindNextFile(hFind, &ffd) == TRUE);
              ::FindClose(hFind);
          } else {
              printf("Failed to find path: %s", path.c_str());
          }
      
          return counter;
      }
      

      【讨论】:

        【解决方案6】:

        从 C++17 开始,它可以使用 STL 完成:

        auto dirIter = std::filesystem::directory_iterator("directory_path");
        
        int fileCount = std::count_if(
            begin(dirIter),
            end(dirIter),
            [](auto& entry) { return entry.is_regular_file(); }
        );
        

        一个简单的for循环也可以:

        auto dirIter = std::filesystem::directory_iterator("directory_path");
        int fileCount = 0;
        
        for (auto& entry : dirIter)
        {
            if (entry.is_regular_file())
            {
                ++fileCount;
            }
        }
        
        

        https://en.cppreference.com/w/cpp/filesystem/directory_iterator

        【讨论】:

          猜你喜欢
          • 2010-11-10
          • 2021-08-25
          • 2011-12-24
          • 2014-01-31
          • 2010-10-15
          • 1970-01-01
          • 1970-01-01
          • 2016-02-19
          • 2011-02-07
          相关资源
          最近更新 更多