目前,我正在尝试在 zip 文件的解压缩过程中获取进度信息。
我正在深入研究具有所有需要的压缩/解压缩算法等的 commons-compress,但我缺少的是以某种方式获取进度信息的东西......在解压缩过程中为用户提供信息控制台等上的示例。我错过了什么吗?也许我还没有仔细阅读文档?
我已经通过使用 java.util.Zip 了解了一些东西,但是 commons compress 是一个更通用的库,它支持不同的格式......
目前,我正在尝试在 zip 文件的解压缩过程中获取进度信息。
我正在深入研究具有所有需要的压缩/解压缩算法等的 commons-compress,但我缺少的是以某种方式获取进度信息的东西......在解压缩过程中为用户提供信息控制台等上的示例。我错过了什么吗?也许我还没有仔细阅读文档?
我已经通过使用 java.util.Zip 了解了一些东西,但是 commons compress 是一个更通用的库,它支持不同的格式......
跟踪输入读取字节数并将其与压缩文件大小进行比较,您可以了解解压缩进度。
我将这个类作为解决方案的近似值粘贴,它用一个跟踪读取大小的包装器包装 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();
}
}
}
}
}
我希望能有所帮助。