在文件搜索中使用进度条

我正在编写一个应用程序,它将从相应的路径中搜索特定的文件。 在搜索过程中,我需要部署一个必须根据搜索运行的进度条。 那我该怎么做呢? 如果可能请发布代码?

这是一个棘手的问题。 我不记得看到任何非索引搜索的实例显示进度条。 (任何人都可以certificate我错了吗?)

我建议使用以下方法(Benny Hallett的建议的延伸),这可能会提供更多的颗粒度。

假设您正在整个文件系统中搜索特定的文件名模式(例如在unix中搜索/上的所有* .jpg文件)

首先将进度条分为N个部分(其中N是搜索根路径中的目录数)。

每次深入到目录heirachy时,分配给父目录的总进程条长度将根据其包含的子目录数进行划分。 完成目录搜索后,分配给它的部分将添加到进度条。 有关更多详细信息,您可以进一步将分配除以当前目录中的文件数+目录数。

此方法应确保您只需遍历目录结构一次,它应该更好地处理不均匀的目录。 (不均匀我指的是搜索成本高和低的目录混合)

举个例子,我们假设一个像这样的目录结构:

/ clipart photos family holiday wallpapers anime landscapes 

(每个缩进指示目录树中更深的级别,并假设所有目录遍历都按字母顺序完成)

你开始看’/’并看到有三个目录( 剪贴画照片壁纸 ),因此你最初将进度条划分为三分之一。

然后,您搜索剪贴画目录,完成后,将进度条更新为三分之一。 然后你进入内部照片 ,看到有两个子目录。 这意味着当你完成搜索家庭时,你会在进度条中添加六分之一,因为有两个子目录( 家庭假日 ),每个子目录的进度构成了分配给照片的三分之一。

总结如下:

完成剪贴画增加了三分之一

完成照片/家庭增加六分之一

完成照片/假期增加六分之一

完成壁纸/动漫增加了六分之一

壁纸/风景的完成增加了六分之一

总共1.0(或100%)(忽略浮点精度)

要使用大多数进度条控件,您需要知道两件事。

  • 你需要做多少事情
  • 你做了多少事

对于第一个,使用目录中的文件数(对于单个目录)或子目录的数量(用于递归访问目录)可能是好的

其次,每次处理文件或目录时都需要更新进度条。

有一个在Swing中使用Progress Bars的教程: 这里

您需要的基本代码是

 JProgressBar progressBar = new JProgressBar(0, getNumberOfFiles()); 

然后使用更新它

 progressBar.setValue(getCurrentNumberProcessed()); 

如果文件或目录的初始数量未知,您可以调用progressBar.setIndeterminate(true)来创建其中一个我不知道这将花费多长时间进度条。 从那里,您可以计算出在执行之前需要处理的文件或目录的数量

 progressBar.setIndeterminate(false); progressBar.setMaximum(numberOfFiles); 

您的搜索程序(SearchFile类 – 最好是单例)应该有一个字段,随着搜索的进行而更新。 例如private double searchProgress; 然后在实际搜索期间更新此字段。

 double searchProgress = 100/noOfTotalFiles; searchProgress = searchProgress + searchProgressIncrement; 

并为您的搜索程序提供公共getter方法。

 public double getProgress(){ return searchProgress;} 

步骤2:使用一个简单的线程来调用程序,每秒(根据需要)轮询进度。

 progressBar.setIndeterminate(false); progressBar.setMaximum(100); Thread t = new Thread(){ @override public void run(){ progressBar.setValue((int)SearchFile.getProgress()); } } 

确保您有适当的逻辑来知道您定期运行此线程的时间。 例如,在SearchFile中更新一个标记,表示搜索已完成。

 while(SearchFile.isRunning()){ Thread.sleep(1000); //sleep for 1 sec progressBar.setValue((int)SearchFile.getProgress()); } 

你仍然可以改善这个……

我使用了Catchwa的方法。 我将进度范围设置为14000,因为我的系统上的操作系统有很多目录。 当我找到一个空目录时,我将小数加权数量添加到进度条。 数量基于深度并按范围标准化。 在每个子树遍历中,你最终得到一个空的目录,并且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); } 

它运行得非常顺畅,价格便宜。 我还为用户提供了一个准确的进度条选项,我首先计算目标总数,这可能很昂贵。

这种事情取决于几个因素。 你是递归寻找文件的吗? 你在寻找什么样的文件? 你在寻找多种类型吗? 您希望进度条如何根据搜索进度进行更新?

另外,你知道如何使用线程吗? 这种问题很可能导致线程的使用(一个用于搜索文件,另一个用于更新进度条)。 如果未使用线程,那么您可能会冒着让UI“挂起”直到搜索完成的风险。