C++ 查找目录中文件数量的有效方法

C++ 查找目录中文件数量的有效方法,c++,C++,我经常需要知道在我的目录结构中的任何给定目录中有多少个文件。但是,由于设备上的内存限制,我无法保留所有目录中文件数量的内存索引。 根据STL文档,我的选择大致如下: #包括 #包括 内部主(空) { std::string path=“.”; 大小\u t计数=0; for(const auto&entry:std::filesystem::directory\u迭代器(path)) { ++计数; } std::cout似乎没有简单的方法。虽然文档中说目录迭代器定义了开始和结束,但它的行为与基

我经常需要知道在我的目录结构中的任何给定目录中有多少个文件。但是,由于设备上的内存限制,我无法保留所有目录中文件数量的内存索引。 根据STL文档,我的选择大致如下:

#包括
#包括
内部主(空)
{
std::string path=“.”;
大小\u t计数=0;
for(const auto&entry:std::filesystem::directory\u迭代器(path))
{
++计数;
}

std::cout似乎没有简单的方法。虽然文档中说目录迭代器定义了开始和结束,但它的行为与基于范围的迭代器不同

1) 返回未更改的
iter

2) 返回构造的默认值
目录\u迭代器
,用作结束迭代器。参数为 忽略。这些非成员函数允许使用
目录\u迭代器
具有基于范围的for循环

#包括
#包括
#包括
名称空间fs=std::filesystem;
int main()
{
fs::directory_迭代器a(“.”);
对于(自动和p:a)

std::cout下面直接使用POSIXAPI,它的速度和内存效率与文件系统无关的方法(C++17)差不多。它还包括“.”和“…”,您可能希望对此进行补偿

#include <dirent.h>
#include <optional>

std::optional<int> dir_entries(const char* path)
{
  DIR* dp{::opendir(path)};
  if (!dp)
  {
    // Alternatively, return -1 instead of an optional, throw an exception, etc.   
    // Jury it still out on this one :)
    return std::nullopt;
  }

  int entries{0};
  while (::readdir(dp.get()))
    ++entries;

  ::closedir(dp);
  return entries;
}
#包括
#包括
std::可选目录项(常量字符*路径)
{
DIR*dp{::opendir(path)};
如果(!dp)
{
//或者,返回-1而不是可选的,抛出异常,等等。
//在这件事上还没有定论:)
返回std::nullopt;
}
int项{0};
while(::readdir(dp.get()))
++参赛作品;
::closedir(dp);
返回条目;
}

Unrelated:如果我没有大错特错的话,这段代码除了计算文件外,还计算目录中的目录。@user4581301,如果您只想限制为常规文件,那么我们还希望忽略符号链接、设备文件、套接字和FIFO。哦,并确定哪些名称引用相同的inode(“硬链接”)这通常不是人们所说的计算文件的意思——这通常是“目录条目”或“文件名”的同义词.使用Qt是一个选项吗?@user4581301是的,它是有意的。因为它们是文件:)@AlexanderS wauw我没有找到那篇文章,这要感谢上百万。你的示例返回
1
是因为你已经在范围基中使用了
a
。所以你没有解释
std::distance(fs::directory\u迭代器(“.”)的错误,fs::directory_迭代器{})
?@t.niese我知道,我忘了添加那个位。增量产生了副作用。除了取决于实现的因素外,距离可能会更慢。这不会是iby编译器无意中发现的,因为运行时会产生副作用。无论如何,感谢移动浏览器。我认为,提供商代理和降低的轮询率也会影响它
#include <fstream>
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;

int main()
{
    fs::directory_iterator a(".");

    for(auto& p: a)
        std::cout << p.path() << '\n';

    //std::cout << (std::end(a) - std::begin(a)) << '\n'; // apparently impossible,
    std::cout << 
              std::distance(a, 
                            fs::directory_iterator()) << '\n'; // always returns 1
    std::cout << 
              std::distance(fs::directory_iterator("."), 
                          fs::directory_iterator{}) << '\n'; // need a new iterator
}
fs::directory_iterator a(".");
int count = 0;
for(auto p: a) {
    ++count;
}
std::cout << count << '\n';
#include <dirent.h>
#include <optional>

std::optional<int> dir_entries(const char* path)
{
  DIR* dp{::opendir(path)};
  if (!dp)
  {
    // Alternatively, return -1 instead of an optional, throw an exception, etc.   
    // Jury it still out on this one :)
    return std::nullopt;
  }

  int entries{0};
  while (::readdir(dp.get()))
    ++entries;

  ::closedir(dp);
  return entries;
}