Files
HW-08-Basic-Multithreading/src/main/java/ProgressMonitor.java
T

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);
}
}
}