Skip to content

Commit

Permalink
Better downloading
Browse files Browse the repository at this point in the history
  • Loading branch information
IndianBartonka committed Sep 19, 2024
1 parent 2147624 commit 2be002a
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 84 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>me.indian.util</groupId>
<artifactId>utils</artifactId>
<version>0.0.5</version>
<version>0.0.5.1</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
Expand Down
20 changes: 17 additions & 3 deletions src/main/java/me/indian/util/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import java.util.Random;
import java.util.concurrent.TimeoutException;
import me.indian.util.download.DownloadListener;
import me.indian.util.download.Downloader;
import me.indian.util.download.DownloadTask;
import me.indian.util.logger.Logger;
import me.indian.util.logger.LoggerConfiguration;
import me.indian.util.system.SystemUtil;
Expand All @@ -17,7 +17,7 @@ public final class Main {
private static final Logger LOGGER = new Logger(new LoggerConfiguration(true, System.getProperty("user.dir") + File.separator + "logs", true)) {
};
private static final Logger LOGGER2 = LOGGER.prefixed("Logger 2");
// private static final Logger LOGGER = new Logger(new LoggerConfiguration(true,
// private static final Logger LOGGER = new Logger(new LoggerConfiguration(true,
// System.getProperty("user.dir") + File.separator + "logs", DateUtil.getFixedDate())) {};
private static final long START_TIME = System.currentTimeMillis();
private static final Random RANDOM = new Random(Integer.MAX_VALUE);
Expand Down Expand Up @@ -131,13 +131,27 @@ public void onEnd(final File outputFile) {
try {
final long start = System.currentTimeMillis();

Downloader.downloadFile(connection.getInputStream(), new File(fileName),
final DownloadTask downloadTask = new DownloadTask(connection.getInputStream(), new File(fileName),
connection.getContentLength(),
BufferUtil.DownloadBuffer.DYNAMIC,
30,
downloadListener
);

LOGGER.info(downloadTask);

new Thread(() -> {
ThreadUtil.sleep(5);
LOGGER.info("Zatrzymywanie pobierania:&b " + fileName);
try {
downloadTask.stopDownload();
} catch (final IOException e) {
throw new RuntimeException(e);
}
}).start();

downloadTask.downloadFile();

LOGGER.info("Pobrano w:&b " + DateUtil.formatTimeDynamic(System.currentTimeMillis() - start, true));
} catch (final TimeoutException e) {
throw new RuntimeException(e);
Expand Down
143 changes: 143 additions & 0 deletions src/main/java/me/indian/util/download/DownloadTask.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package me.indian.util.download;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeoutException;
import me.indian.util.BufferUtil;
import me.indian.util.DateUtil;
import me.indian.util.MathUtil;
import org.jetbrains.annotations.Nullable;

public class DownloadTask {

private final InputStream inputStream;
private final File outputFile;
private final long fileSize;
private final BufferUtil.DownloadBuffer downloadBuffer;
private final int timeOutSeconds;
private final DownloadListener downloadListener;
private boolean canDownload, downloading, finished;

public DownloadTask(final InputStream inputStream, final File outputFile, final long fileSize, final BufferUtil.DownloadBuffer downloadBuffer, final int timeOutSeconds, @Nullable final DownloadListener downloadListener) throws IOException, TimeoutException {
this.inputStream = inputStream;
this.outputFile = outputFile;
this.fileSize = fileSize;
this.downloadBuffer = downloadBuffer;
this.timeOutSeconds = timeOutSeconds;
this.downloadListener = downloadListener;
this.canDownload = true;
this.downloading = false;
}

public DownloadTask(final InputStream inputStream, final File outputFile, final long fileSize, final BufferUtil.DownloadBuffer downloadBuffer, final int timeOutSeconds) throws IOException, TimeoutException {
this.inputStream = inputStream;
this.outputFile = outputFile;
this.fileSize = fileSize;
this.downloadBuffer = downloadBuffer;
this.timeOutSeconds = timeOutSeconds;
this.downloadListener = null;
this.canDownload = true;
this.downloading = false;
}

public void downloadFile() throws IOException, TimeoutException {
final long inactivityTimeoutMillis = DateUtil.secondToMillis(this.timeOutSeconds);
long lastActivityTime;

try (final FileOutputStream fileOutputStream = new FileOutputStream(this.outputFile)) {
this.downloading = true;
final int definedBuffer = BufferUtil.defineBuffer(this.downloadBuffer, this.fileSize);
final byte[] buffer = new byte[definedBuffer];

if (this.downloadListener != null)
this.downloadListener.onStart(this.downloadBuffer, definedBuffer, this.outputFile);

int bytesRead;
long totalBytesRead = 0;

long lastTime = System.currentTimeMillis();
long lastBytesRead = 0;
int lastProgress = -1;

while ((bytesRead = this.inputStream.read(buffer)) != -1) {
if (!this.canDownload) break;

lastActivityTime = System.currentTimeMillis();
fileOutputStream.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;


final long currentTime = System.currentTimeMillis();
final double elapsedTime = (currentTime - lastTime) / 1000.0;
if (elapsedTime >= 1.0) {
final long bytesSinceLastTime = totalBytesRead - lastBytesRead;
final double speedBytesPerSecond = (double) bytesSinceLastTime / elapsedTime;
final double speedMBps = speedBytesPerSecond / BufferUtil.DownloadBuffer.ONE_MB.getBuffer();
lastTime = currentTime;
lastBytesRead = totalBytesRead;

final int progress = Math.round((float) totalBytesRead / (float) this.fileSize * 100.0f);

final double formatedSpeed = MathUtil.format(speedMBps, 3);
final long remainingTimeSeconds = (long) (MathUtil.bytesToMB(this.fileSize) / formatedSpeed);
final String remainingTimeString = DateUtil.formatTimeDynamic(remainingTimeSeconds * 1000, true);

if (this.downloadListener != null)
this.downloadListener.onSecond(progress, formatedSpeed, remainingTimeString);

if (progress != lastProgress) {
lastProgress = progress;

if (this.downloadListener != null)
this.downloadListener.onProgress(progress, formatedSpeed, remainingTimeString);
}
}

if (this.timeOutSeconds != -1 && System.currentTimeMillis() - lastActivityTime > inactivityTimeoutMillis) {
if (this.downloadListener != null) this.downloadListener.onTimeout(this.timeOutSeconds);
throw new TimeoutException();
}
}

this.inputStream.close();

if (this.downloadListener != null) this.downloadListener.onEnd(this.outputFile);
} finally {
this.downloading = false;
this.finished = true;
}
}

public boolean isCanDownload() {
return this.canDownload;
}

public boolean isDownloading() {
return this.downloading;
}

public boolean isFinished() {
return this.finished;
}

public void stopDownload() throws IOException {
if (!this.downloading) throw new IllegalStateException("Brak aktywnego pobierania.");
this.canDownload = false;
this.inputStream.close();
}

@Override
public String toString() {
return "DownloadTask (" +
"outputFile=" + this.outputFile.getPath() +
", fileSize=" + this.fileSize +
", downloadBuffer=" + this.downloadBuffer +
", timeOutSeconds=" + this.timeOutSeconds +
", canDownload=" + this.canDownload +
", downloading=" + this.downloading +
", finished=" + this.finished +
')';
}
}
80 changes: 0 additions & 80 deletions src/main/java/me/indian/util/download/Downloader.java

This file was deleted.

0 comments on commit 2be002a

Please sign in to comment.