Recently I did some project that included traversing directories, for
files, or directories only. In the process I used cli, so to payback I
want to donate DirectoryIterator to commons-lang project. This is
non-recursive iterator. Can be very useful, and can save a lot of time
when dealing with directories, and files. The file is dependent on java2
(LinkedList used as stack) but it is not difficult for me to change it
to use Stack, or vector, or something from commons-collections. As
example of use there is Prune example witch uses iterator to prune all
empty folders in some given root.
If you like it you can put it in commons. If it's inappropriate to post
things this way, please explain me how to propose things in the future.
Mit freundlichen Grüßen,
Best Regards,
River
Intertele AG
import java.io.File;
/**
* Simple command line program that prunes empty directories given arbitrary
* path.
* @author <code>River</code>
* @version 1.0
*/
public class Prune {
/**
* Entery point of this program
* @param args command line arguments
*/
public static void main(String[] args) {
if (args.length == 0) {
printUsage();
System.exit(-1);
}
File root = new File(args[0]);
if (root.list() != null && root.list().length == 0) {
rmdir(root);
} else {
DirectoryIterator iter = new DirectoryIterator(root,
DirectoryIterator.DIRS_ONLY);
while (iter.hasNext()) {
File dir = iter.nextFile();
System.out.println("Examing: " + dir);
String[] children = dir.list();
if (children != null && children.length == 0) {
rmdir(dir);
File parent = dir.getParentFile();
while ( (parent.list() != null)
&& (parent.list().length == 0)) {
rmdir(parent);
if (parent.equals(root)) {
break; // do not pass root;
}
parent = parent.getParentFile();
}
}
}
}
}
private static void rmdir(File dir) {
System.out.print("REMOVING EMPTY DIR: " + dir + " ... ");
if (dir.delete()) {
System.out.println("ok");
} else {
System.out.println("FAILED");
}
}
private static void printUsage() {
System.err.println(" Usage:");
System.err.println(" java " + Prune.class.getName() + " <dir>");
}
}import java.io.File;
import java.io.FileFilter;
import java.util.Iterator;
import java.util.LinkedList;
/**
* Class that give ability to user to iterate through directories. Actualy
* implementation uses files for iteration, but since directory iteration is
* most common usage example of this class name is DirectoryIterator, and not
* FileIterator.
*
* @author <code>River</code>
* @version 1.0
*/
public class DirectoryIterator implements Iterator {
/**
* Convinient implementation of FileFilter interface that accepts files
* and directories.
*/
public static final FileFilter ALL = new FileFilter() {
public boolean accept(File file) {
return true;
}
};
/**
* Implementation of FileFilter interface that accepts only files. This
* implementation is here just for the sake of style, since with that
* filter class is behaving like iterator over
* <code>root.listFiles()</code> array.
*/
public static final FileFilter FILES_ONLY = new FileFilter() {
public boolean accept(File file) {
return file.isFile();
}
};
/**
* Implementation of FileFilter interface that accepts only directories.
*/
public static final FileFilter DIRS_ONLY = new FileFilter() {
public boolean accept(File file) {
return file.isDirectory();
}
};
private final File root;
private final LinkedList todo = new LinkedList();
private final FileFilter filter;
private File last = null;
/**
* Create iterator with <code>root</code> as starting point of iteration.
* Note that root will never be returned from nextXXX() methods.
* @param root
*/
public DirectoryIterator(File root) {
this(root, ALL);
}
/**
* Create iterator over <code>root</code> using <code>filter</code>
* FileFilter.Note that root will never be returned
* from nextXXX() methods.
* @param root root directory for iteration
* @param filter FileFilter implementation that will
* limit returned objects.
*/
public DirectoryIterator(File root, FileFilter filter) {
if (root == null) {
throw new IllegalArgumentException("root can't be null");
}
if (filter == null) {
filter = ALL;
}
this.root = root;
this.filter = filter;
addChildren(root);
}
/**
* Returns root File of this DirectoryIterator.
* @return File representing root of iteration.
*/
public File getRoot() {
return root;
}
/**
* put childs in todo stack. Before putting childs filter will be called
* with file in question.
* @param root
*/
private void addChildren(File root) {
File[] children = root.listFiles();
if (children != null) {
for (int i = children.length - 1; 0 <= i; i--) {
if (filter.accept(children[i])) {
todo.addFirst(children[i]);
}
}
}
}
/**
* Return next File.
* @return Object representing File.
*/
public Object next() {
return nextFile();
}
/**
* Type safe method for returning next object of iteration.
* @return next File in iteration.
*/
public File nextFile() {
File file = (File) todo.removeFirst();
if (file.isDirectory()) {
addChildren(file);
}
last = file;
return file;
}
/**
* Removes last returned File. Note that you don't have any way to
* determine weather deletion was successfull, so users are advised to
* use other ways of file deletion. This method is implemented just
* because it is in Iterator interface.
*/
public void remove() {
if (last != null) {
last.delete();
last = null;
}
}
/**
* Returns <code>true</code> if iterator has more elements to iterate
* trought.
* @return <code>true</code> if there is more elements in iterator,
* <code>false</code> otherwise.
*/
public boolean hasNext() {
return!todo.isEmpty();
}
/**
* Test method. If everything is ok this will output all files on syste
* to the stdout.
* @param args Command line arguments
*/
public static void main(String[] args) {
File[] roots = File.listRoots();
int count = 1; // counter of files
for (int root = 0; root < roots.length; root++) {
DirectoryIterator iter = new DirectoryIterator(roots[root]);
while (iter.hasNext()) {
System.out.println((count++) + " - " + iter.nextFile());
}
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]