Java 在文件搜索中使用进度条
我正在编写一个应用程序,它将从相应的路径中搜索一个或多个特定的文件。在搜索过程中,我需要部署一个进度条,它必须根据搜索运行。那我怎么能做到呢?如果可能的话,请张贴代码 这种事情取决于几个因素。您是在递归地查找该文件吗?你在找什么样的文件?你要找多种类型的吗?您希望进度条如何相对于搜索进度进行更新Java 在文件搜索中使用进度条,java,Java,我正在编写一个应用程序,它将从相应的路径中搜索一个或多个特定的文件。在搜索过程中,我需要部署一个进度条,它必须根据搜索运行。那我怎么能做到呢?如果可能的话,请张贴代码 这种事情取决于几个因素。您是在递归地查找该文件吗?你在找什么样的文件?你要找多种类型的吗?您希望进度条如何相对于搜索进度进行更新 另外,你知道如何使用线程吗?这种问题很可能导致使用线程(一个用于搜索文件,另一个用于更新进度条)。如果未使用线程,则在搜索完成之前,您的UI可能会一直处于“挂起”状态。要使用大多数进度条控件,您需要了解
另外,你知道如何使用线程吗?这种问题很可能导致使用线程(一个用于搜索文件,另一个用于更新进度条)。如果未使用线程,则在搜索完成之前,您的UI可能会一直处于“挂起”状态。要使用大多数进度条控件,您需要了解两件事
- 你需要做多少事情
- 你做了多少事
JProgressBar progressBar = new JProgressBar(0, getNumberOfFiles());
然后使用
progressBar.setValue(getCurrentNumberProcessed());
如果文件或目录的初始数量未知,您可以调用progressBar.setUndeterminate(true)
创建其中一个,我不知道这将花费进度条多长时间。从那里,您可以计算出在执行此操作之前需要处理多少文件或目录
progressBar.setIndeterminate(false);
progressBar.setMaximum(numberOfFiles);
这是一个棘手的问题。我不记得看到过任何显示进度条的非索引搜索实例。(谁能证明我错了?) 我建议使用下面的方法(Benny Hallett建议的扩展)来提供更多的授权 假设您正在整个文件系统中搜索特定的文件名模式(例如,在unix中,搜索/上的所有*.jpg文件) 首先将进度条分成N个部分(其中N是搜索根路径中的目录数) 每次深入目录heirachy时,分配给父目录的总进程条长度将根据其包含的子目录数进行划分。目录搜索完成后,分配给它的部分将添加到进度栏。有关更多详细信息,您可以进一步将分配除以当前目录中的文件数+目录数 此方法应确保只需遍历目录结构一次,并且它应能更好地处理不均匀的目录。(我所说的不均匀是指搜索成本高低的目录的混合) 作为一个示例,让我们假设如下目录结构:
/
clipart
photos
family
holiday
wallpapers
anime
landscapes
(每个缩进表示目录树中更深的一层,假设所有目录遍历都是按字母顺序进行的)
您首先查看“/”并看到有三个目录(剪贴画、照片和墙纸),因此您最初将进度条划分为三个
然后搜索clipart目录,完成后,将进度条更新为三分之一。然后你进入照片里面,看到有两个子目录。这意味着,当您完成家庭搜索时,您将在进度栏中添加六分之一,因为有两个子目录(家庭和假日),并且每一个子目录的进度占分配给照片的三分之一的一半
总而言之:
剪贴画的完成增加了三分之一
完成照片/家庭增加六分之一
完成照片/假期增加六分之一
壁纸/动画的完成增加了六分之一
壁纸/风景画的完成增加了六分之一
对于总数为1.0(或100%)(忽略浮点精度)的搜索程序(SearchFile类-最好是singleton)应该有一个字段,该字段将随着搜索的进行而更新。例如私人双搜索进度
然后在实际搜索期间更新此字段
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,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);
...
if(dir.size()){
m_dirsAtDepth[++m_depth]=目录大小();
}
否则{
qreal乘积=1.00;
对于(int i=1;i是的,使用线程将是更好的选择。但我需要当前正在搜索的文件项应显示在progressbar下方…是的,多类型文件朋友。想法很好,但不知道目录的数量,我们如何才能找到完成级别?用一个示例阐明我的答案。希望这有助于解释我的t思考。只要不断增加吧台,让它停在99%,然后在你完成搜索后继续。我总觉得这是大多数吧台/加载所做的,因为它们往往需要很长时间才能到达吧台的尽头。-/谢谢benny,是不是