Scanning directories for files in java – the iterator way
This program I am sharing here can be used to get all files inside a specified root directory and its sub-directories and generate a list of files. There are other articles on this problems that generates file list using an recursive method call and. Function is called recursively each time a folder or folder is encountered. The problem with this approach is when number of files and directory level increases the efficiency becomes very poor, for cases like C:\WINDOWS or C:\Program Files that code failed and RAM /disk usage reaches to 100%.
The one here I am sharing is very cute code which will work like an iterator in collection framework, when you call the next() method all files in that root will be returned and root directory will be changed to sub-directory, a subsequent call will thus fetch files from next level directory. There is no question of overloading the computer here because now you are getting the files in step by step. I have tested this code with C:\WINDOWS and doing a right click property check for that folder the number from windows console turns out to be exactly the same.
======== code ======
package com.columnit.filenotify.scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import org.apache.log4j.Logger;
import com.columnit.filenotify.solrj.SolrjServer;
/**
* Scanning files recursively from a directory
*
* @author Abhishek Kaushik
*/
public class NewScanFiles{
public static boolean DOINDEX = true;
public int level = 0; //Directory level
public int count = 0; //Accumulative number of files
public static HashMap<Integer, HashMap<Integer, String>> schemaRoot = new HashMap<Integer, HashMap<Integer, String>>();
public static int currentFolderIndex = 0; //Identifies folders in same level
public static int countLevelFolders = 1; //For initial root directory
private static Logger log = Logger.getLogger(SolrjServer.class);
public static void main(String[] args){
DOINDEX = true;
try {
NewScanFiles nsf = new NewScanFiles("C:\\Windows");
while(nsf.hasNext()){
//
nsf.next();
}
System.out.println("count="+nsf.count);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public NewScanFiles(String folderUrl) throws FileNotFoundException{
File file = new File(folderUrl);
if(!file.exists()){
throw new FileNotFoundException();
}
if(DOINDEX){
HashMap<Integer, String> hm = new HashMap<Integer, String>();
hm.put(0, folderUrl);
schemaRoot.put(0, hm);
}
}
public String getNextRoot(){
return schemaRoot.get(level).get(currentFolderIndex);
}
public boolean hasNext(){
return schemaRoot.get(level).size() != 0;
}
public Collection<String> next() {
Collection<String> all = new ArrayList<String>();
String folder = getNextRoot();
HashMap<Integer, String> hm = new HashMap<Integer, String>();
File file = new File(folder);
try{
File[] childs = file.listFiles();
int folderCount = 0;
for(int i=0; i<childs.length; i++){
if(childs[i].isFile()){
all.add(childs[i].getPath());
count++;
}else{
hm.put(folderCount, childs[i].getPath());
folderCount++;
}
}
if(currentFolderIndex == 0){
schemaRoot.put(level+1, hm);
}else{
HashMap<Integer, String> thm = schemaRoot.get(level+1);
int existingCount = thm.size();
for(int i=0; i<hm.size(); i++){
thm.put(existingCount+i, hm.get(i));
}
}
if(currentFolderIndex < countLevelFolders - 1){
currentFolderIndex++;
}else{
currentFolderIndex = 0;
countLevelFolders = schemaRoot.get(level+1).size();
level++;
}
schemaRoot.remove(level - 1);
log.info("folder="+folder+" level="+level+" currentFolderIndex="+currentFolderIndex);
// System.out.println("folder="+folder+" level="+level+" currentFolderIndex="+currentFolderIndex);
return all;
}catch(NullPointerException e){
// e.printStackTrace();
log.error("Failed to get content of : "+folder+e.getStackTrace());
currentFolderIndex++;
}catch(Exception e){
// e.printStackTrace();
log.error("Exception caught: "+ e.getStackTrace());
}
return null;
}
}