According to the documentation of Files.Walk
( Javadoc ) this is not possible. given that this method has no way of registering a "listener", or some event that indicates partial results, but on the other hand with Files.walkFileTree
(Javadoc ) If possible, you can implement a counting, or manipulation more to your liking.
The following example uses a SwingWorker ( Javadoc ) with intermediate results that are sent via the method publish
to UI UI
and the final result can be obtained via get()
:
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingWorker;
public abstract class SwingWalter extends SwingWorker<String, String> {
private int counter = 0;
private long lastpublishTime;
private final Path Root;
public SwingWalter(Path tonavigate) {
Root = tonavigate;
}
@Override
protected String doInBackground() throws Exception {
lastpublishTime = System.currentTimeMillis();
Files.walkFileTree(Root, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
if (System.currentTimeMillis() - lastpublishTime > 5000) {
publish(String.format("Current PathCount: %s, navigating to Path: %s ", counter, dir.toString()));
lastpublishTime = System.currentTimeMillis();
}
counter++;
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (System.currentTimeMillis() - lastpublishTime > 5000) {
publish(String.format("Current PathCount: %s, looking at: %s ", counter, file.toString()));
lastpublishTime = System.currentTimeMillis();
}
counter++;
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
publish(String.format("unable to visit Path: %s , ignoring...", file.toString()));
return FileVisitResult.CONTINUE;
}
});
return String.format("Files on %s are: %s ", Root.toString(), counter);
}
@Override
protected final void process(List<String> chunks) {
UpdateUIText(String.join(System.lineSeparator(), chunks));
}
@Override
protected final void done() {
try {
UpdateUIText(String.format("%s%s","Task Completed result: ", get()));
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(TestFrame.class.getName()).log(Level.SEVERE, null, ex);
}
completed();
}
/*este metodo es llamado via el EDT(event dispatch thread)
el cual es un hilo de ejecucion seguro para actualizar
componentes de Swing)*/
protected abstract void UpdateUIText(String Text);
/*este metodo es llamado via el EDT (hilo de ejecucion seguro para
actualizar componentes de Swing),
este se llama cuando el SwingWalter concluye su ejecucion
por tanto este lo pude utilizar para cambiar estados que requieren
que finalize el "background task"
*/
protected abstract void completed();
}
to use this SwingWorker is done in a similar way to:
//....
private SwingWorker<String, String> tmpworker;
private javax.swing.JButton Btexecute;
private javax.swing.JTextArea txtOutput;
//....
//definicion del UI Y metodos etc...
//....
private SwingWorker<String, String> getWorker(Path tonavigate) {
return new SwingWalter(tonavigate) {
@Override
protected void UpdateUIText(String Text) {
try {
//txtouput es un TextArea
txtOutput.getDocument().insertString(txtOutput.getDocument().getLength(), String.format("%s%s", System.lineSeparator(),Text), null);
} catch (BadLocationException ex) {
Logger.getLogger(TestFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
protected void completed() {
//free something unlock a button maybe?
}
};
}
//...
//BtexecuteActionPerformed es el evento de un botton que ejecuta el Swingworker
private void BtexecuteActionPerformed(java.awt.event.ActionEvent evt) {
if (tmpworker == null || tmpworker.isDone()) {
tmpworker = getWorker(Paths.get("C:\"));
tmpworker.execute();
}
}
NOTE:
in the example I use if (System.currentTimeMillis() - lastpublishTime > 5000) {
to ensure that for every file that is surfed if ah elapsed 5000
or more Milisegundos
or 5 segundos
realize a Publish to the UI with the file that is currently browsing.