here a code snippet that shows how to track progress of WebClient and DataBufferUtils.write
public DownloadProgress download(String url, String targetFile) {
WebClient client = WebClient.builder()
.clientConnector(
new ReactorClientHttpConnector(HttpClient.create().followRedirect(true)
))
.baseUrl(url)
.build();
final DownloadProgress progress = new DownloadProgress();
Flux<DataBuffer> dataBufferFlux = client.get()
.exchangeToFlux( response -> {
long contentLength = response.headers().contentLength().orElse(-1);
progress.setLength(contentLength);
return response.bodyToFlux(DataBuffer.class);
});
Path path = Paths.get(targetFile);
FileOutputStream fout = null;
try {
fout = new FileOutputStream(path.toFile());
} catch (FileNotFoundException e) {
throw new RuntimeException("Unable to create targetFile", e);
}
DataBufferUtils.write(dataBufferFlux, progress.getOutputStream(fout) )
.subscribe( DataBufferUtils.releaseConsumer() );
return progress;
}
This method returns a "DownloadProgress" object updated while the outpout stream is written.
Here is this DownloadProgress class :
public class DownloadProgress {
private long contentLength = -1;
private long downloaded;
public void setLength(long contentLength) {
this.contentLength = contentLength;
}
public OutputStream getOutputStream(FileOutputStream fileOutputStream) {
return new FilterOutputStream(fileOutputStream) {
@Override
public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
downloaded += len;
}
@Override
public void write(int b) throws IOException {
out.write(b);
downloaded++;
}
@Override
public void close() throws IOException {
super.close();
done();
}
};
}
public void done() {
if ( contentLength == -1 ) {
contentLength = downloaded;
} else {
downloaded = contentLength;
}
}
public double getProgress() {
if ( contentLength == -1 ) return 0;
return downloaded / (double) contentLength;
}
public long getDownloaded() {
return downloaded;
}
public boolean finished() {
return downloaded > 0 && downloaded == contentLength;
}
}
Then, to monitor the download you can loop while finished returns false and display the progress.
do {
String progress = String.format("%.2f", dl.getProgress() * 100.0);
log.info( "Downloaded: {}%", progress );
try {
Thread.sleep(250);
} catch (InterruptedException e) {
return;
}
} while(!dl.finished());
Hope this could help.