【问题标题】:Is there any faster way to get a directory size in Windows than iterate over all its children?有没有比遍历所有子目录更快的方法来获取 Windows 中的目录大小?
【发布时间】:2014-09-27 21:53:41
【问题描述】:

我的程序需要获取所有子目录和子文件的目录大小,它通过递归枚举该目录中的所有对象并总结大小来实现。但是,对于大型目录,性能是不可接受的。它比 Windows 资源管理器目录属性计算的大小要长,并且它会导致硬盘驱动器更加嘎嘎作响。那么,我该如何优化这个过程呢?是否有任何合适的 WinAPI 函数或方法?

【问题讨论】:

  • 据我所知,您的操作方式是“属性”对话框的操作方式。文件系统将缓存目录内容,因此如果您首先运行程序,属性对话框会看起来更快,因为数据已经在内存中。
  • @JonathanPotter:我知道其中涉及到一些缓存,并且我已经进行了足够多的实验以清楚地看到,即使 Properties 正在做同样的事情,它也是以一种更优化的方式来做的。而且我不确定如何优化它。
  • @PawełStawarz:这只有在您知道当前目录的基数至少比所有其他目录大一点的情况下才有效。而且我看不出这可以通过通用代码知道。如果您确实知道“我的分区专用于此目的,并且只包含这些目录”,您可以这样做,但对于通用功能,递归迭代目录是唯一的方法。
  • 今天一个 TB 的驱动器需要一分钟多的时间来迭代。所以你的问题归结为“我如何告诉用户他想知道什么而不让他等待?”很简单:你向他展示你正在努力。用户不会感到惊讶。
  • 对 FILE_ID_BOTH_DIR_INFO 使用 GetFileInformationByHandleEx 可能比使用 FindFirstFile 和 FindNextFile 更快。

标签: c++ windows winapi directory


【解决方案1】:

遍历目录中的文件是唯一通用的方法,而且 Windows 肯定没有任何捷径可以做到这一点(在以用户级权限运行的常规应用程序中 - 我不建议你应用程序应该需要管理员权限才能运行!)。

如果目录包含大量文件,则可能会有所不同,具体取决于您是对目录进行深度优先还是广度优先递归 - 广度优先需要“保存”目录在当前目录中搜索,如果您有许多目录,这当然也可能导致问题,其中深度优先方法不需要任何存储,但这意味着操作系统将同时打开更多目录 - 并且可能会产生更多头部动作。然而,这很可能是一个微小的差异。对于大型文件系统,“使用了多少空间”可能会有所不同——我实际上还没有尝试过。

【讨论】:

  • 我不同意这种观点,即“Windows 肯定没有任何捷径可以做到这一点”。直接访问Master File Table (MFT) 很可能比遍历目录中的文件快很多
  • @IInspectable:但只有以提升权限运行的应用程序才能做到这一点。我将修改“用于常规应用程序”。
  • @IInspectable:据我所知,MFT 包含除文件所在目录之外的所有内容。这使得 MFT 方法只适用于根目录。
  • @MSalters:目录索引信息也可用,可用于过滤 MFT 记录。
猜你喜欢
  • 2011-01-07
  • 1970-01-01
  • 2014-01-22
  • 2012-04-07
  • 2012-02-27
  • 2013-10-09
  • 1970-01-01
  • 1970-01-01
  • 2018-12-12
相关资源
最近更新 更多