File 扫描硬盘时的进度条

File 扫描硬盘时的进度条,file,progress-bar,directory,File,Progress Bar,Directory,因此,我正在做一个简单的扫描,以获得硬盘上所有文件夹的列表(c:\windows和c:\windows\system32被视为单独的条目)。如果我想为这个1-2分钟的任务提供一个进度条,我会怎么做?也就是说,我知道如何制作progressbar,但不确定如何确定完成了多少工作 编辑:请注意,执行预扫描不是一个解决方案,因为此扫描仅获取文件夹列表,而预扫描将花费同样长的时间 下面是代码示例。在我的系统上干净运行不到2分钟,但由于磁盘访问缓存,第二次运行不到10秒。我在此基础上创建了基于堆栈而不是基

因此,我正在做一个简单的扫描,以获得硬盘上所有文件夹的列表(c:\windows和c:\windows\system32被视为单独的条目)。如果我想为这个1-2分钟的任务提供一个进度条,我会怎么做?也就是说,我知道如何制作progressbar,但不确定如何确定完成了多少工作

编辑:请注意,执行预扫描不是一个解决方案,因为此扫描仅获取文件夹列表,而预扫描将花费同样长的时间

下面是代码示例。在我的系统上干净运行不到2分钟,但由于磁盘访问缓存,第二次运行不到10秒。我在此基础上创建了基于堆栈而不是基于递归的变体

我发现的一种机制可能不是100%可靠,但比我的扫描速度快得多,它是通过管道将“dir/s/ab/b”传输到我的程序并计算换行符的实例。Dir做了一些魔术,比我的程序扫描我的高清效果好得多,但我不知道那是什么魔术

class Program
{
    static void recurse(string pos)
    {
        DirectoryInfo f = new DirectoryInfo(pos);
        try
        {
            foreach (DirectoryInfo x in f.GetDirectories("*"))
            {
                recurse(x.FullName);
            }
        } catch (Exception) {}
    }
    static void Main(string[] args)
    {
        recurse("c:\\");
    }
}

不要用它。尝试一些更合适的方法,如旋转动画或Kitts样式栏:。

你可以用几种方法来实现……一个简单的过程可能不是100%准确

开始之前,获取文件计数,然后使用该计数计算完成百分比,在处理X个文件后更新进度。假定查找有性能成本。也许只需要获得根目录的计数,并在遍历时更新进度

另一种选择可能是简单地记录“上次运行”详细信息的计数,并使用它来计算百分比,同样,不一定100%准确,而是一个选项


我想我想到的其他一些事情是简单地向用户显示一个“正在进行”的对话框,而不是试图得到一个百分比。否则,可能只是显示当前的工作目录,表明您正在取得进展。

如果您不能递归目录结构,因为这将花费与执行任务一样长的时间,那么您最好猜测有多少文件夹。真的

也许您可以使用基于过去历史的算法(例如,上次我这样做时,共有150个目录,而有10个顶级目录,因此,很好的猜测是当前顶级目录数量的15倍)


告诉用户某事需要一段时间(不知道确切的时间)的另一种方法是使用倒计时。即使你已经猜到某件事情需要比实际需要更长的时间(比如说5分钟,而实际上这是一个3分钟的任务),至少用户知道大概需要多长时间。当它比他们被告知的更快完成时,他们会更高兴。当然,唯一令人不快的是,如果你在另一边猜错了,也就是说,如果某件事比你想象的要花更长的时间。然后他们坐在那里等待(在他们看来)应该已经完成的事情完成。

您可以创建一个具有递增最大值属性的进度条。如果您的最大属性最初设置为100,则在计时器的滴答声事件中,将最大值和值都增加1,例如,这样您将有下面列出的值

         Maximum    Value 
Tick1:    101          1   - 1% 
Tick2:    102          2   - 2%
Tick3:    103          3   - 3% 
TickN:    100+n        n 
Finish    100+n      100+n - 100%  --> force to fill the progress bar

您可以试验初始最大值,使进度条移动更平滑。

如果您需要制作进度条,并且无法抽出时间收集准确信息,则无法制作完美的进度条。考虑到这一假设,您仍然可以制作一个并非完全不准确的进度条

例如,您可以创建一个函数,根据当前目录中的子目录数对进度条进行细分。因此,如果根目录有10个子目录,则将进度条的10%分配给每个目录。然后,进入第一个子目录并计算其子目录数。如果有5个,则将进度条前10%的20%分配给每个进度条(总进度条的2%)。继续这样做,直到到达一个没有子目录的目录,在那里进行处理,并增加进度条,不管它代表什么分数


进度条上的每个%并不代表算法完成的工作量相同,但考虑到您的限制,我怀疑您能做得更好。

我尝试获取“
dir/ad/b/s c://
”的标准输出并计算行数。这相当快。它可以在progressbar中使用,但不能作为目录列表使用。

我使用了Catchwa的方法。我将进度范围设置为14000,因为我系统上的操作系统大约有那么多dir。当我找到一个空目录时,我将分数加权的数量添加到进度条中。基于深度并使用范围标准化的量。在每一次子树遍历中,最终都会得到一个空的dir,dir中所有空子目录的权重构成dir的权重,但会被分成若干块。当我找到一个非空目录时,我将子目录的数量存储在一个映射中。使用Qt,我得到:

emit findProgressBar_setRange(14000); ... if (dir.size()) { m_dirsAtDepth[++m_depth] = dir.size(); } else { qreal product = 1.00; for (int i = 1; i <= m_depth; ++i) { product *= m_dirsAtDepth[i]; } int x = qRound((1.00 / product) * 14000); emit findProgressBar_addValue(x); }

emit findProgressBar_setRange(14000)。。。如果(dir.size()){m_dirsAtDepth[++m_depth]=dir.size();}否则{qreal product=1.00;对于(int i=1;正如我所说,此扫描所做的只是获取一个文件夹列表。任何像您建议的解决方案都需要与我的扫描一样长的时间。假设您使用的是.NET之类的工具,您可能会使用DirectoryInfo.GetDirectory(String,SearchOption)之类的工具,然后使用返回集合的计数。因此它应该接近即时…Rich:不,因为我正在获取所有目录。如果您的解决方案有效,我将只使用该函数进行扫描。@Brian-我想这就回避了您当时在做什么的问题。创建文件夹列表不应该花费那么长时间。我有一个系统that解析15000个文件