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