我试图跟踪压缩过程的进度。自动取款机我是这样做的:
public static void compressGzipTest(final OutputStream os, final File source) throws CompressorException,
IOException
{
final CountingInputStream cis = new CountingInputStream(new FileInputStream(source));
final GzipCompressorOutputStream gzipOut = (GzipCompressorOutputStream) new CompressorStreamFactory()
.createCompressorOutputStream(CompressorStreamFactory.GZIP,os);
new Thread() {
public void run()
{
try
{
long fileSize = source.length();
while (fileSize > cis.getBytesRead())
{
Thread.sleep(1000);
System.out.println(cis.getBytesRead() / (fileSize / 100.0));
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}.start();
IOUtils.copy(cis,gzipOut);
}
这很好,但我需要这个线程,这个线程提供关于进程的反馈,不是在这个方法中实现的,而是在调用它时(为了在android设备上创建progressbar之类的东西)。所以这更像是一个架构问题。有什么解决办法吗?
最佳答案
同时,我通过覆盖ioutils.copy()来解决这个问题,方法是添加一个接口作为参数:
public static long copy(final InputStream input, final OutputStream output, int buffersize,
ProgressListener listener) throws IOException
{
final byte[] buffer = new byte[buffersize];
int n = 0;
long count = 0;
while (-1 != (n = input.read(buffer)))
{
output.write(buffer,0,n);
count += n;
listener.onProgress(n);
}
return count;
}
然后是这样叫的
copy(input, output, 4096, new ProgressListener() {
long totalCounter = 0;
DecimalFormat f = new DecimalFormat("#0.00");
@Override
public void onProgress(long bytesRead)
{
totalCounter += bytesRead;
System.out.println(f.format(totalCounter / (fileSize / 100.0)));
}
});
我现在面临的唯一挑战是,限制控制台上的输出不是针对每个字节[4096],而是针对每个两兆字节。我试过这样的方法:
while (-1 != (n = input.read(buffer)))
{
output.write(buffer,0,n);
count += n;
while(n % 2097152 == 0)
{
listener.onProgress(n);
}
}
return count;
但那根本不能给我任何结果