I was having one requirement that is I have to write a high performance file search program, the program is supposed to list down all the files and folder that matches the name pattern provided starting from the topmost folder and searching recursively in subfolders.
program can be command line main class with the following input
The top folder to start search . example that is C:\MyFolders
Type of item to search. File or folder or both
Search pattern java regular expression (java.util.regex) are accepted as paatern
example MFile.tx? will find UMFile123.txt and AIIMFile.txs’
Timeout (in secs) by which application must return. otherwise it must return with “could not complete operation ” message.
I have come up with anoter approach that is..
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");
}
}
}
the other file is…
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..!
Where fileFilter could look something like this
This basically guarantees that the list of files returned will match the criteria in the
FileFilterNow, it’s semantics in this case, because in order for the
listFilesmethod to work, it will still need to iterate over all the files anyway.You could try maintaining a single instance of the filter, rather then recreating it over each iteration, but you will need to profile the difference between your algorithm and any benefits that this might bring.
On a side note, you could deploy a
Threadqueue of some kind, where each thread is responsible for checking the matches of a given directory and queuing any new sub directories. Just a thoughtReusable Pattern
These are the basic changes I’ve made, but really, you have to decide if they work.
I’d just like to say, here’s a fish, now you need to learn to fish 😉