2012-08-06 71 views
-1

我有一個要求是我必須編寫一個高性能的文件搜索程序,該程序應該列出與從最頂層文件夾開始提供的名稱模式相匹配的所有文件和文件夾,以及在子文件夾中遞歸搜索。文件搜索高性能程序

程序可以是命令行主類具有以下輸入

的頂層文件夾以啓動搜索。示例是C:\ MyFolders 要搜索的項目的類型。文件或文件夾或兩者 搜索模式的Java正則表達式(java.util.regex中)被接受爲paatern

例如MFILE .tx?會發現應用程序必須返回的UMFile123.txt和AIIMFile.txs' 超時(以秒爲單位)。否則必須以「無法完成操作」消息返回。

我想出了anoter做法是..

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.util.List; 

import com.sapient.test.fileSearch.FileSearch; 

public class FilesearchMain { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     int flag=0; 
     System.out.println("Type Item to Search "); 
     System.out.println("1 File"); 
     System.out.println("2 Folder "); 
     System.out.println("3 Both"); 
     System.out.println("0 Exit"); 

     try{ 
     BufferedReader readType = new BufferedReader(new InputStreamReader(System.in)); 


     String searchType =readType.readLine();; 

     System.out.println("Enter name of file to search ::"); 

     BufferedReader readName = new BufferedReader(new InputStreamReader(System.in)); 
     String fileName=readName.readLine(); 


     if(searchType==null && fileName==null){ 
      throw new Exception("Error Occured::Provide both the input Parameters"); 
     } 
     validateInputs(searchType,fileName); 
     FileSearch fileSearch = new FileSearch(searchType,fileName); 
List resultList=fileSearch.findFiles(); 
     System.out.println(resultList); 
     }catch(IOException io){ 
      System.out.println("Error Occured:: Check the input Parameters and try again"); 
     }catch(Exception e){ 
      System.out.println(e.getMessage()); 
     } 
    } 

    private static void validateInputs(String searchType, String fileName) 
    throws Exception{ 
     if(!(searchType.equals("1") || searchType.equals("2") || searchType.equals("3"))){ 
      throw new Exception("Error:: Item to search can be only 1 or 2 or 3"); 
     } 
     if(searchType.equals("") || fileName.equals("")){ 
      System.out.println("Error Occured:: Check the input Parameters and try again"); 

     } 

    } 

} 

其他文件...

public class FileSearch { 
    private String searchType; 
    private String fileName; 

    public FileSearch(){ 

    } 
    public FileSearch(String sType,String fName){ 
     this.searchType=sType; 
     this.fileName=fName; 
    } 

    public String getSearchType() { 
     return searchType; 
    } 
    public void setSearchType(String searchType) { 
     this.searchType = searchType; 
    } 
    public String getFileName() { 
     return fileName; 
    } 
    public void setFileName(String fileName) { 
     this.fileName = fileName; 
    } 
    public List findFiles(){ 

     File file = new File("C:\\MyFolders"); 

     return searchInDirectory(file); 

    } 
    //Assuming that files to search should contain the typed name by the user 
    // 
    private List searchInDirectory(File dirName){ 
     List<String> filesList = new ArrayList<String>(); 
     if(dirName.isDirectory()){ 
      File [] listFiles = dirName.listFiles(); 
      for(File searchedFile : listFiles){ 
       if(searchedFile.isFile() && searchedFile.getName().toUpperCase().contains(getFileName().toUpperCase())&& 
         (getSearchType().equals("1") || getSearchType().equals("3"))){ 
        filesList.add(searchedFile.getName()); 
       }else if(searchedFile.isDirectory() && searchedFile.getName().toUpperCase().contains(getFileName().toUpperCase()) 
        && (getSearchType().equals("2") || getSearchType().equals("3"))){ 
        filesList.add(searchedFile.getName()); 
        searchInDirectory(searchedFile); 
       }else{ 
        searchInDirectory(searchedFile); 
       } 
      } 
     } 
     return filesList; 
    } 

} 


Please advise is this approach is correct as per design..! 
+1

有沒有你爲什麼選擇不使用'File.listFiles(的FileFilter)'任何理由? – MadProgrammer 2012-08-06 05:42:21

+0

@MadProgrammer你能否請更正我錯了更新後的帖子..! – user1577449 2012-08-06 05:46:43

+0

@ user1577449:他正確地建議你應該對內置函數進行基準測試,看看它是否足夠好,然後再重新創建它。以下是一個示例:http://docs.oracle.com/javase/tutorial/essential/io/find.html。或者這個:http://www.exampledepot.com/egs/java.io/GetFiles.html – paulsm4 2012-08-06 05:47:38

回答

4
if (topFolderOrFile.isDirectory()) { 
     File[] subFoldersAndFileNames = topFolderOrFile.listFiles(fileFilter); 

哪裏的FileFilter可能看起來像這樣

public class MyFileFilter implements FileFilter{ 

    public boolean accept(File pathname) { 
     return fileNamePattern.matcher(pathname.getName()).find(); 
    } 

} 

這基本上保證th返回的文件列表將與FileFilter中的條件匹配

現在,在這種情況下它是語義的,因爲爲了使listFiles方法正常工作,它仍然需要迭代所有文件。

您可以嘗試維護過濾器的單個實例,而不是在每次迭代中重新創建它,但是您需要分析算法與這可能帶來的任何好處之間的差異。

在附註上,您可以部署某種Thread隊列,其中每個線程負責檢查給定目錄的匹配並排隊所有新的子目錄。只是一個想法

可重用的模式

public static void searchFile(String topFolderName, String type, 
     String fileNamePatternRegExp, long timeOut) throws IOException { 

    long startTimeStamp = Calendar.getInstance().getTimeInMillis(); 

    File topFolderOrFile = new File(topFolderName); 
    Pattern fileNamePattern = Pattern.compile(fileNamePatternRegExp); 

    searchFile(topFolderName, type, fileNamePattern, long timeOut); 

} 

public static void searchFile(String topFolderName, String type, 
     Pattern fileNamePattern, long timeOut) throws IOException { 
    //... 
} 

這是我做了基本的變化,但實際上,你必須決定是否他們的工作。

public static class PatternFileFilter implements FileFilter { 

    private Pattern fileNamePattern; 

    public PatternFileFilter(Pattern fileNamePattern) { 

     this.fileNamePattern = fileNamePattern; 

    } 

    @Override 
    public boolean accept(File pathname) { 

     return fileNamePattern.matcher(pathname.getName()).find() || pathname.isDirectory(); 

    } 

    public Pattern getPattern() { 
     return fileNamePattern; 
    } 
} 

public static void searchFile(File topFolderOrFile, String type, PatternFileFilter filter, long timeOut) throws IOException { 

    long startTimeStamp = Calendar.getInstance().getTimeInMillis(); 

    if (topFolderOrFile.isDirectory()) { 

     File[] subFoldersAndFileNames = topFolderOrFile.listFiles(filter); 
     if (subFoldersAndFileNames != null && subFoldersAndFileNames.length > 0) { 
      for (File subFolderOrFile : subFoldersAndFileNames) { 

       if (ITEM_TYPE_FILE.equals(type) && subFolderOrFile.isFile()) { 
        System.out.println("File name matched ----- " 
          + subFolderOrFile.getName()); 
       } 
       if (ITEM_TYPE_FOLDER.equals(type) 
         && subFolderOrFile.isDirectory() && filter.getPattern().matcher(subFolderOrFile.getName()).find()) { 
        System.out.println("Folder name matched ----- " 
          + subFolderOrFile.getName()); 
       } 
       if (ITEM_TYPE_FILE_AND_FOLDER.equals(type) && filter.getPattern().matcher(subFolderOrFile.getName()).find()) { 
        System.out.println("File or Folder name matched ----- " 
          + subFolderOrFile.getName()); 
       } 

       // You need to decide if you want to process the folders inline 
       // or after you've processed the file list... 

       if (subFolderOrFile.isDirectory()) { 
        long timeElapsed = startTimeStamp 
          - Calendar.getInstance().getTimeInMillis(); 
        if (((timeOut * 1000) - timeElapsed) < 0) { 
         System.out 
           .println("Could not complete operation-- timeout"); 
        } else { 
         searchFile(subFolderOrFile, type, 
           filter, (timeOut * 1000) 
           - timeElapsed); 
        } 
       } 
      } 

     } 

    } 

} 

public static void searchFile(String topFolderName, String type, String fileNamePatternRegExp, long timeOut) throws IOException { 

    File topFolderOrFile = new File(topFolderName); 
    Pattern fileNamePattern = Pattern.compile(fileNamePatternRegExp); 

    searchFile(topFolderOrFile, type, new PatternFileFilter(fileNamePattern), timeOut); 

} 

我只想說,這裏的魚,現在你需要學會的魚;)

+0

@ MadProgrammer..please你可以張貼的完整代碼,因爲我已經做到了這將是一個很大的幫助,使我的理解更加清晰..!Thnaks提前。 – user1577449 2012-08-06 06:02:52

+0

請發表oplete代碼,因爲我已經這樣做了,這將使從理解開始更加清晰,非常感謝 – user1577449 2012-08-06 06:10:18