Reputation: 2549
I'm listing the files on a file system in Java using the following Apache Commons class:
Collection<File> allFiles = FileUtils.listFiles(rootDirectory, null, recursive);
This is a very long process, and can take up to 5 minutes.
Is there any way I can check the size of the collection while it is being populated?
I tried accessing it from a separate thread but simply got zero until the process was ready.
Upvotes: 12
Views: 232
Reputation: 19185
I guess you can you try using executing platform specific commands like redirecting list command output to temp file and reading it using Java File API.
ls > temp.txt
I created a simple shell script which will list files in given index.
#!/bin/bash
RANGE_UP=$2
RANGE_BOT=$1
CURRENT_CNTR=0
FILENAME=._m_ls
ls -w 1 > $FILENAME
while read line
do
if [ $CURRENT_CNTR -le $RANGE_UP -a $CURRENT_CNTR -gt $RANGE_BOT ]; then
printf $line"\n"
fi
CURRENT_CNTR=`expr $CURRENT_CNTR + 1`
done < $FILENAME
You can now do something like ./ls_range.sh 10000 30000 >temp.txt
and then read from this file using BufferedReader
in a different thread.
Upvotes: 1
Reputation: 11543
You could use the FileUtils IOFileFilter.
Collection<File> listFiles = FileUtils.listFiles(new File("."), counter, FileFilterUtils.trueFileFilter());
where counter would be along the lines
IOFileFilter counter = new IOFileFilter() {
@Override
public boolean accept(File arg0, String arg1) {
countCall();
return true;
}
@Override
public boolean accept(File arg0) {
countCall();
return true;
}
};
and countCall is the method which updates progress.
Upvotes: 2
Reputation: 16615
Your only way to do this (as opposed to java7 or splitting the work like previously suggested) would be to write your own code to search through the file system while updating a callback.
I used code from commons-io
, and modified it to suit your needs, obviously it needs testing, but it counts the files as they are found.
EXAMPLE
interface Counter {
void foundFile(File file);
}
final class FileSearcher {
public static Collection<File> listFiles(File root, FileFilter filter, Counter counter) {
Collection<File> files = new ArrayList<File>();
File[] found = root.listFiles(filter);
if (found != null) {
for (int i = 0; i < found.length; i++) {
if (found[i].isDirectory()) {
files.addAll(listFiles(found[i], filter, counter));
} else {
files.add(found[i]);
counter.foundFile(found[i]);
}
}
}
return files;
}
}
And then use it like this:
final AtomicInteger inte = new AtomicInteger(0);
FileSearcher.listFiles(new File("C:/"), null, new Counter() {
@Override
public void foundFile(File file) {
System.out.println("found file number " + inte.addAndGet(1));
}
});
Upvotes: 1
Reputation: 328659
Until you get a return value from the method, you won't be able to access the collection as it gets populated, because you don't have access to the variable that this method uses internally.
You could split the search in smaller pieces by not using the recursive flag and deal with the recursion yourself to receive a collection per directory.
A better alternative, if you are using Java 7, is to use the FileVisitor
interface to explore the file system. It has a few callback methods that enable you to track the progress.
Upvotes: 11