125 lines
4.1 KiB
Java
125 lines
4.1 KiB
Java
import java.util.List;
|
|
|
|
public class ProgressMonitor implements Runnable {
|
|
|
|
private final String fileName;
|
|
private final int totalSizeMB;
|
|
private final List<ChunkStatus> chunks;
|
|
private final long monitorDelayMs;
|
|
private double previousTotalDownloadedMB;
|
|
private long previousTimeMs;
|
|
|
|
|
|
public ProgressMonitor(DownloadConfig config, List<ChunkStatus> chunks) {
|
|
this.fileName = config.getFileName();
|
|
this.totalSizeMB = config.getTotalSizeMB();
|
|
this.chunks = chunks;
|
|
this.monitorDelayMs = 500;
|
|
this.previousTotalDownloadedMB = 0.0;
|
|
this.previousTimeMs = System.currentTimeMillis();
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
// Repeatedly check chunk progress until all chunks are completed.
|
|
// In each loop:
|
|
// 1. Read the downloaded size from every chunk
|
|
// 2. Add all downloaded amounts to totalDownloadedMB
|
|
// 3. Count completed chunks
|
|
// 4. Print a progress message
|
|
// 5. If completedChunks == chunks.size(), print a final monitor message and stop
|
|
// 6. Otherwise, sleep for monitorDelayMs and continue
|
|
while (true) {
|
|
double totalDownloadedMB = 0.0;
|
|
int completedChunks = 0;
|
|
|
|
for (ChunkStatus chunk : chunks) {
|
|
totalDownloadedMB += chunk.getDownloadedMB();
|
|
|
|
if (chunk.isCompleted()) {
|
|
completedChunks++;
|
|
}
|
|
}
|
|
|
|
double percent = 0.0;
|
|
if (totalSizeMB > 0) {
|
|
percent = (totalDownloadedMB * 100.0) / totalSizeMB;
|
|
}
|
|
|
|
long currentTimeMs = System.currentTimeMillis();
|
|
long timeDiffMs = currentTimeMs - previousTimeMs;
|
|
double downloadedDiff = totalDownloadedMB - previousTotalDownloadedMB;
|
|
|
|
double speedMBps = 0.0;
|
|
if (timeDiffMs > 0){
|
|
speedMBps = (downloadedDiff * 1000.0) / timeDiffMs;
|
|
}
|
|
|
|
double etaSeconds = 0.0;
|
|
if (speedMBps > 0 && totalDownloadedMB < totalSizeMB){
|
|
double remainingMB =totalSizeMB - totalDownloadedMB;
|
|
etaSeconds = remainingMB / speedMBps;
|
|
}
|
|
|
|
previousTotalDownloadedMB = totalDownloadedMB;
|
|
previousTimeMs = currentTimeMs;
|
|
|
|
|
|
int barWidth = 50;
|
|
int filledWidth = (int)(barWidth * percent / 100.0);
|
|
|
|
System.out.print("[");
|
|
for (int i = 0; i < barWidth; i++) {
|
|
if (i < filledWidth){
|
|
System.out.print("=");
|
|
}else if (i == filledWidth && percent< 100){
|
|
System.out.print(">");
|
|
}else {
|
|
System.out.print(" ");
|
|
}
|
|
}
|
|
System.out.print("]");
|
|
|
|
System.out.printf(
|
|
"Progress for %s: %.1f/%.1f MB (%.2f%%), completed chunks: %d/%d%n , ETA: %s",
|
|
fileName,
|
|
totalDownloadedMB,
|
|
(double) totalSizeMB,
|
|
percent,
|
|
completedChunks,
|
|
chunks.size(),
|
|
speedMBps,
|
|
formatETA(etaSeconds)
|
|
);
|
|
|
|
if (completedChunks == chunks.size()){
|
|
System.out.println("All chunks have been downloaded successfully!");
|
|
break;
|
|
}
|
|
|
|
try {
|
|
Thread.sleep(monitorDelayMs);
|
|
} catch (InterruptedException e) {
|
|
System.out.println("Progress monitor interrupted.");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
private String formatETA(double etaSeconds){
|
|
if (etaSeconds <= 0){
|
|
return "Calculating ...";
|
|
}
|
|
int hours = (int)(etaSeconds/3600);
|
|
int minutes = (int)((etaSeconds%3600)/60);
|
|
int secondes = (int)(etaSeconds %60);
|
|
|
|
if (hours > 0){
|
|
return String.format("%dh %dm %ds" , hours, minutes, secondes);
|
|
}else if(minutes > 0){
|
|
return String.format("%dm %ds" , minutes, secondes);
|
|
}else{
|
|
return String.format("%ds", secondes);
|
|
}
|
|
}
|
|
}
|