Java用廣度優先搜索快速搜索文件


背景

在開發的過程中,經常需要在文件系統里按某些條件搜索文件,比如音樂播放器掃描音樂,而搜索文件,大多人喜歡用遞歸的方式,而這也是最容易想到的方式。遞歸方式如果文件夾很深就容易造成棧溢出,而且不斷的壓棧退棧也會使搜索效率變低。我們常用的文件通常不會放在太深的文件夾,我們應該一層一層下去搜索,放在淺層目錄先被搜索,如果實時顯示結果,得到想要的結果即停止,用廣度優先搜索的優勢就更能體現出來了。

|--E:/
	|--Music/
		|--pop/
			|--Jay/
			|--Leehom Wang/
		|--rock/
			|--beyond/
	|--QQ/
	|--q.mp3
	|--k.mp3

假設有以上的目錄結構,E:/是要搜索的根目錄,搜索的的內容是后綴為mp3的文件,名稱加斜杠的表示文件夾,只有名稱的表示文件。

1. 如果用遞歸,它會依次搜索Music->pop-> LeehomWang->rock->beyond->QQ然后才到我們mp3文件,假設Music這個目錄很深,它會一直搜下去,而我們在淺層目錄的MP3文件卻要等到最后才搜到。

2. 如果用廣度優先搜索,我們一下子就可以搜索到我們的MP3文件,而且不需要壓棧和退棧,如果文件夾數很多明顯可以加快搜索速度。

總之在文件搜索時用廣度優先搜索優於深度優先搜索(遞歸)

代碼

/**
	 * 廣度優先搜索文件或文件夾
	 * @param path 要搜索的目錄
	 * @param regex 搜索的通配符
	 * @param isDisplyDir 是否在搜索結果中顯示文件夾
	 * @param isDisplayFile 是否在搜索結果中顯示文件
	 */
	private static void bfsSearchFile(String path,String regex,boolean isDisplyDir,boolean isDisplayFile)
	{
		if(!(isDisplayFile||isDisplyDir))
		{
			throw new IllegalArgumentException("isDisplyDir和isDisplayFile中至少要有一個為true");
		}
		Queue<File> queue=new LinkedList<>();
		File[] fs=new File(path).listFiles();
		//遍歷第一層
		for(File f:fs)
		{
			//把第一層文件夾加入隊列
			if(f.isDirectory())
			{
				queue.offer(f);
			}
			else
			{
				if(f.getName().matches(regex)&&isDisplayFile)
				{
					System.out.println(f.getName());
				}
			}
		}
		//逐層搜索下去
		while (!queue.isEmpty()) {
			File fileTemp=queue.poll();//從隊列頭取一個元素
			if(isDisplyDir)
			{
				if(fileTemp.getName().matches(regex))
				{
					System.out.println(fileTemp.getAbsolutePath());
				}
			}
			
			File[] fileListTemp=fileTemp.listFiles();
			if(fileListTemp==null)
				continue;//遇到無法訪問的文件夾跳過
			for(File f:fileListTemp)
			{
				if(f.isDirectory())
				{
					queue.offer(f);////從隊列尾插入一個元素
				}
				else
				{
					if(f.getName().matches(regex)&&isDisplayFile)
					{
						System.out.println(f.getName());
					}
				}
			}
			
		}
	}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM