登陆 注册

JAVA递归思想实现全盘搜索文件系统之进阶版

守望者 2020-03-24 272人围观 ,发现0个评论 java

      上一篇我们通过文章 JAVA递归思想实现全盘检索文件系统之基础版 了解到了全盘检索搜索文件系统所用到的核心思想——递归思想,

这一片文章所要讲解的实例将在上一篇基础上进行改进,主要借助多线程提升检索搜索文件系统的速度。


    上一篇文章检索搜索文件系统的大体流程就是,先搜C盘,再搜D盘,再搜E盘。。。。我们可以看到,这样一个盘一个盘的搜下去,还是太慢了,

那么有没有办法多个盘符一起搜索呢,这样就能大大缩短检索文件的时间? 答案是可以的,这里我们主要借助多线程思想,为保证线程安全,

这里还将用到线程锁,小伙伴们还可以学习或者巩固一下关于线程方面的知识。


解析:


    这里工具类相比上次多了一些全局变量,关于他们代表的含义请看下面实例代码中旁边的注释。

   下面我来讲解一下globleSearchFile()函数关键部分:


这里遍历文件系统盘符,为每一个盘符开一个线程,线程里面调用searchFile()函数执行文件搜索,

多个线程同时运行,多个盘符同时进行搜索,效率大大提高


线程里面searchFile()函数执行完毕后对结果进行判断:


 1.  如果find为true,则表示找到目标文件,调用findFile()函数,将全局变量find赋值true,

     由于所有线程里面在执行searchFile()函数时,开头都会做如下判断


     if(find) {return false;}


   这表示如果找到目标文件,则立即返回,不再查找

   所以此时(找到目标文件)所有线程停止查找,立即执行结束

   这样做的好处就是避免不必要的系统资源的消耗


2. 如果find为false,则表示搜索完整个盘符后仍然没有找到目标文件,然后调用notFile()函数

   search_num变量加一,当搜索完毕的盘数的数量达到最大值,即表示全盘搜索完毕,如下:

 if(search_num==disk_num) {   // 全盘搜索完毕,激活锁
			    	  synchronized (object) {
							 over = true;						
							 object.notify();
							
						}
			      } // if search_num==disk_num

此时激活锁,返回全盘搜索结果,全盘搜索完毕。


实例代码如下,可以测试一下:

package m1;

import java.io.File;

public class Test {
	 
     String find_path = null;       // 目标文件所在的路径(如果有的话)
	
	Object object = new Object();   // 线程锁
	volatile boolean find = false;   // 目标文件是否找到
	boolean over = false;            //整个文件系统是否检索搜索完毕
	
	Object object2 = new Object();   // 线程锁
	int disk_num = 0;                // 盘符数量
	int search_num = 0;              // 已搜索完毕的盘符数量
	
		public void find_file() {    // 找到文件后调用该函数,激活锁
			
            synchronized (object) {
				 
				 over = true;
				 find = true;
				 object.notify();      
//				 System.out.println("find path="+dir_path);
				
			}
		}
		public void not_findFile() {    //搜索完盘符后没有找到目标文件,调用该函数
			
			 synchronized (object2) {			     
				 search_num++;
			      if(search_num==disk_num) {   // 全盘搜索完毕,激活锁
			    	  synchronized (object) {
							 over = true;						
							 object.notify();
							
						}
			      } // if search_num==disk_num
			}
		}
		// 搜索文件核心函数(递归函数)
		public  boolean searchFile(String dir_path,String des_fileName) {
				
			 if(find) {return false;}
			 
			 File dir_file = new File(dir_path);
			 File[] files = dir_file.listFiles();
			 
//			 if(dir_file.isFile()&&dir_file.getName().equals(des_fileName)) {find_file(dir_file.getAbsolutePath());}
			  if(files!=null) {
				 for(File file:files) {
					 
					 if(file.isDirectory()) {
		                boolean exist =  searchFile(file.getAbsolutePath(),des_fileName);
		                 if(exist) {return true;}
		                 else {continue;}
					 }
					 else {
					//	 System.out.println("file: "+file.getAbsolutePath());
					//	 if(file.getName().equals(des_fileName)) {return true;}
						 
						 String file_name = file.getName();
						 
						 if(file_name.equals(des_fileName)) { 
							 find_path = file.getAbsolutePath();
							 return true;
						 }

					}  // if is file
				 }    // for
			 }
			  
			return false;
		 }  //  list_files
	
	//全盘搜索文件系统入口函数
  public String globleSearchFile(String des_fileName) {
		  File[] roots = File.listRoots();
		  
		  for(File file:roots) {
			  
			  			 new Thread(new Runnable() {
			  		// 遍历盘符,为每一个盘符开启一个线程,开始搜索目标函数		
			  				@Override
			  				public void run() {
			  					boolean find = searchFile(file.getAbsolutePath(), des_fileName);
			  					   if(find) {find_file();}   //盘符搜索完毕后,对搜索结果进行判断处理
			  					   else {not_findFile();}
			  				}
			  			}).start();
			    	   
			      } // for		  
		  
		  synchronized (object) {   //线程锁,如果搜索完毕,则释放锁,结束全盘搜索,返回搜索结果
			  while(!over) {
				  try {
					object.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			  }
		}
		  
//		  System.out.println("find? "+find);

		  return find_path;
		 
	 }
	 
	 public static void main(String[] args) {
		
		 long start_time = System.currentTimeMillis();
		 
		 System.out.println("start find...");
		 Test searchFile = new Test();
		 String path = searchFile.globleSearchFile("wslk_strings.xml");
		 
		 if(path!=null) {System.out.println("already find, file path :"+path);}
		 else {System.out.println("sorry,not find the file");}
		 
		 System.out.println("用时:"+((System.currentTimeMillis()-start_time))+"毫秒");
//		 new SearchFile().new SearchThread("G:\\", "ToolTip.html").start();
		 
	}
}


    转载请附上本文链接:https://tufeng.xyz/java/26.html,谢谢合作!

请发表您的评论
请关注微信公众号
微信二维码