Progress bar with Apache FileUtils.copyDirectory(…

2019-06-23 19:47发布

问题:

Does anyone know any way of implementing progress bar for Apache's FileUtils.copyDirectory(File src, File dst)? I don't see anything helpful in JavaDocs and API. Seems like a common use case in dealing with batch disk operations, so I'm not sure if I miss something obvious.

回答1:

I guess you will have to do that yourself. I see this immediate solution:

  1. Find all files you are about to copy and count the number or total file size first (depending on what your progress bar should measure)
  2. Copy the files using FileUtils.copyDirectory(File, File, FileFilter) and "abuse" the FileFilter as a callback to communicate progress to your progress bar


回答2:

For anyone interested, I did this by coping the doCopyFile method from FileUtils and the couple of methods that lead up to it. I then pasted them into a new class so that I could edit the methods rather than only using the fixed FileUtils methods.

Then I changed this part of the doCopyFile method:

pos += output.transferFrom(input, pos, count);

To this: (update the progress bar every time the buffer is emptied, not the best way)

//Split into into deceleration and assignment to count bytes transfered
long bytesTransfered = output.transferFrom(input, pos, count);
//complete original method
pos += bytesTransfered;
//update total bytes copied, so it can be used to calculate progress
bytesTransferedTotal += bytesTransfered;
//your code to update progress bar here
ProgressBar.setValue((int) Math.floor((100.0 / totalSize) * bytesTransferedTotal));

For a better way the copy would be run in a different thread, and the progress bar would be updated in the EDT (using the bytesTransfered value and the total size of the files that are being copied):

long bytesTransfered = output.transferFrom(input, pos, count);
pos += bytesTransfered;
bytesTransferedTotal += bytesTransfered;

Then to update the progress bar on the EDT fire events with something like this:

ProgressBar.setValue((int) Math.floor((100.0 / totalSizeOfFiles) * bytesTransferedTotal));