Skip to content

Commit 992f73d

Browse files
rtroiloaoles
authored andcommitted
feat: add progress logger to Downloader.downloadFile
feat: prevent divide by zero feat: prevent divide by zero
1 parent 613a13d commit 992f73d

File tree

2 files changed

+94
-2
lines changed

2 files changed

+94
-2
lines changed

core/src/main/java/com/graphhopper/util/Downloader.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@
1717
*/
1818
package com.graphhopper.util;
1919

20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
22+
2023
import java.io.*;
2124
import java.net.HttpURLConnection;
2225
import java.net.URL;
26+
import java.nio.file.Path;
2327
import java.util.function.LongConsumer;
2428
import java.util.zip.GZIPInputStream;
2529
import java.util.zip.Inflater;
@@ -29,6 +33,7 @@
2933
* @author Peter Karich
3034
*/
3135
public class Downloader {
36+
private static final Logger logger = LoggerFactory.getLogger(Downloader.class);
3237
private static final int BUFFER_SIZE = 8 * 1024;
3338
private final String userAgent;
3439
private String referrer = "http://graphhopper.com";
@@ -111,8 +116,10 @@ public void downloadFile(String url, String toFile) throws IOException {
111116
InputStream iStream = fetch(conn, false);
112117
BufferedOutputStream writer = new BufferedOutputStream(new FileOutputStream(toFile), BUFFER_SIZE);
113118
InputStream in = new BufferedInputStream(iStream, BUFFER_SIZE);
114-
try {
115-
in.transferTo(writer);
119+
String file = Path.of(toFile).getFileName().toString();
120+
logger.info("Downloading {} [{}]", url, conn.getContentLengthLong());
121+
try (OutputStream progress = new ProgressOutputStream(writer, "downloading %s ..".formatted(file), conn.getContentLengthLong(), logger::info)) {
122+
in.transferTo(progress);
116123
} finally {
117124
Helper.close(iStream);
118125
Helper.close(writer);
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.graphhopper.util;
2+
3+
import org.apache.commons.lang3.time.DurationFormatUtils;
4+
import org.apache.commons.lang3.time.StopWatch;
5+
6+
import java.io.IOException;
7+
import java.io.OutputStream;
8+
import java.util.function.Consumer;
9+
10+
class ProgressOutputStream extends OutputStream {
11+
private final OutputStream out;
12+
private final long max;
13+
private final Consumer<String> log;
14+
private final String progressRenderString;
15+
16+
private long current = 0;
17+
private long speed = 0;
18+
19+
private final StopWatch time;
20+
private final StopWatch totalTime;
21+
22+
23+
public ProgressOutputStream(OutputStream out, String task, long max, Consumer<String> log) {
24+
this.out = out;
25+
this.max = max;
26+
this.log = log;
27+
if (max > 0) {
28+
this.progressRenderString = "%s %%%dd/%d (%%3d%%%%) [%%.2f MB/s / %%.2f MB/s] %%s"
29+
.formatted(task, Long.toString(max).length(), max);
30+
} else {
31+
this.progressRenderString = "%s %%d/? [%%.2f Mbps / %%.2f Mbps] %%s".formatted(task);
32+
}
33+
34+
this.time = StopWatch.createStarted();
35+
this.totalTime = StopWatch.createStarted();
36+
37+
}
38+
39+
private void progress(long n) {
40+
current += n;
41+
speed += n;
42+
if (time.getTime() >= 1000) {
43+
triggerLog();
44+
time.reset();
45+
time.start();
46+
speed = 0;
47+
}
48+
}
49+
50+
private void triggerLog() {
51+
log.accept(render((speed) / (Math.max(time.getTime(), 1) * 1000.0), (current) / (Math.max(totalTime.getTime(), 1) * 1000.0)));
52+
}
53+
54+
private String render(double mbits, double mbitsTotal) {
55+
if (max > 0) {
56+
return progressRenderString
57+
.formatted(current, (int) ((current / (double) max) * 100),
58+
mbits, mbitsTotal,
59+
DurationFormatUtils.formatDuration(totalTime.getTime(), "mm:ss.SSS"));
60+
}
61+
return progressRenderString
62+
.formatted(current,
63+
mbits, mbitsTotal,
64+
DurationFormatUtils.formatDuration(totalTime.getTime(), "mm:ss.SSS"));
65+
66+
}
67+
68+
@Override
69+
public void write(byte[] b, int off, int len) throws IOException {
70+
out.write(b, off, len);
71+
progress(len);
72+
}
73+
74+
@Override
75+
public void write(int b) throws IOException {
76+
out.write(b);
77+
progress(1);
78+
}
79+
80+
@Override
81+
public void close() throws IOException {
82+
out.close();
83+
triggerLog();
84+
}
85+
}

0 commit comments

Comments
 (0)