com.weaverplatform.util.ProgressInputStream Maven / Gradle / Ivy
package com.weaverplatform.util;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
// Based on https://stackoverflow.com/questions/27890287/how-to-publish-progress-for-large-json-file-parsing-with-gson
public class ProgressInputStream extends FilterInputStream {
private final int size;
private long bytesRead;
private int percent;
private List listeners = new ArrayList<>();
// If size is less than 1 the value is interpret to be unknown
public ProgressInputStream(InputStream in, int size) {
super(in);
this.size = size;
bytesRead = 0;
percent = 0;
}
public void addListener(Listener listener) {
listeners.add(listener);
}
public void removeListener(Listener listener) {
listeners.remove(listener);
}
@Override
public int read() throws IOException {
int b = super.read();
updateProgress(1);
return b;
}
@Override
public int read(byte[] b) throws IOException {
return updateProgress(super.read(b));
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
return updateProgress(super.read(b, off, len));
}
@Override
public long skip(long n) throws IOException {
return updateProgress(super.skip(n));
}
@Override
public void mark(int readLimit) {
throw new UnsupportedOperationException();
}
@Override
public void reset() throws IOException {
throw new UnsupportedOperationException();
}
@Override
public boolean markSupported() {
return false;
}
private T updateProgress(T numBytesRead) {
if(size < 1) {
return numBytesRead;
}
if (numBytesRead.longValue() > 0) {
bytesRead += numBytesRead.longValue();
if (bytesRead * 100 / size > percent) {
percent = (int) (bytesRead * 100 / size);
for (Listener listener : listeners) {
listener.onProgressChanged(Math.min(percent, 100));
}
}
}
return numBytesRead;
}
public interface Listener {
void onProgressChanged(int percentage);
}
}