目前我正在尝试在zip文件的解压缩过程中获取进度信息。
我深入研究了所有需要压缩/解压缩算法的commons-compress等,但是我所缺少的是以某种方式获取进度信息...在解压缩过程中为用户提供控制台等信息。我是否遗漏了什么?也许我还没有仔细阅读文档?
我已经通过使用java.util.Zip查看了一些内容,但是commons compress是一个支持不同格式的更通用的库......
答案 0 :(得分:0)
跟踪输入读取字节数并将其与压缩文件大小进行比较,您可以获得解压缩进度的指示。
我将此类粘贴为解决方案的近似值,它使用包装器封装FileInputStream,该包装器跟踪读取大小并调用回调以在控制台中打印进度:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
public final class Gz {
protected static interface GzProgress {
public void progress(long read, long max);
}
protected static final class GzConsoleProgress implements GzProgress {
protected final int incr;
protected int lastPercent;
protected GzConsoleProgress(int incr) {
this.incr = incr;
this.lastPercent = 0;
}
@Override
public void progress(long read, long max) {
final int percent = (int) (read * 100 / max);
if (percent >= lastPercent + incr) {
final int items = (percent - lastPercent) / incr;
for (int i = 0; i < items; i++) {
System.out.print('#');
}
lastPercent = percent % incr == 0 ? percent : (percent - percent % incr);
}
}
}
protected static final class GzProgressInputStream extends BufferedInputStream {
protected final long max;
protected long read;
protected final GzProgress progress;
protected boolean end;
protected GzProgressInputStream(InputStream is, long max, GzProgress progress) {
super(is);
this.max = max;
this.read = 0;
this.progress = progress;
end = false;
}
@Override
public synchronized int read(byte[] b, int off, int len) throws IOException {
final int r = super.read(b, off, len);
if (r > 0) {
read += r;
progress.progress(read, max);
end = read == max;
}
return r;
}
@Override
public void close() throws IOException {
try {
super.close();
} finally {
if (!end) {
progress.progress(max, max);
}
}
}
}
public static void main(String[] args) {
if (args == null || args.length == 0) {
System.out.println("Usage: java " + Gz.class.getName() + " file1.gz file2.gz ...");
} else {
final int progressPercent = 10;
for (final String filename : args) {
final File file = new File(filename);
if (file.exists() && filename.toLowerCase().endsWith(".gz")) {
final File outFile = new File(filename.replaceAll(".gz$", ""));
System.out.println("Extracting " + filename + " ...");
final long length = file.length();
try (final InputStream is = new GZIPInputStream(new GzProgressInputStream(new FileInputStream(file),
length, new GzConsoleProgress(progressPercent)));
final OutputStream os = new BufferedOutputStream(new FileOutputStream(outFile))) {
final byte[] buff = new byte[512];
int r = 0;
while ((r = (is.read(buff))) != -1) {
os.write(buff, 0, r);
}
} catch (final IOException e) {
System.err.println("Error extracting " + filename + ": " + e.getMessage());
}
System.out.println();
}
}
}
}
}
我希望能提供帮助。