2012-08-06 32 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