ZipInputStream不报告读取的*实际*(即压缩)字节
-
05-07-2019 - |
题
喜欢这个网站!我的问题如下:
我正在读取一个来自HTTP“PUT”网络的zip文件。请求。请求标头告诉我Content-Length是(例如)1Mb。以下代码创建ZipInputStream,并将zip内容保存到当前目录中的文件:
ZipInputStream zis = new ZipInputStream(inputStream);
ZipEntry ze;
long totalBytesRead = 0;
while ((ze = zis.getNextEntry()) != null) {
BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(ze.getName()));
byte[] buffer = new byte[4096];
int i;
while ((i = zis.read(buffer)) != -1) {
totalBytesRead+=i;
outStream.write(buffer,0,i);
}
outStream.close();
}
inputStream.close();
完成所有操作后, totalBytesRead
等于大约1.5Mb(取决于文件的压缩,可能是任何东西!)。我想知道的是,是否有办法找出从原始的 inputStream
中读取了多少实际字节?对于每个压缩条目, ze.getSize()
和 ze.getCompressedSize()
都返回-1(即它不知道)。我需要这个信息用于进度条,以显示已从网络读取传输的zip文件的字节数。
连连呢?我是否应该继承ZipInputStream并尝试找出它从包装的InputStream读取的字节数?
提前致谢!
解决方案
当然,这似乎是合理的。
基本上有两个选项:读取所有字节,存储它们(在内存或文件中),计算它们,然后解压缩它们;当它们进来时计算它们。前者似乎效率低下,后者需要 InputStream
的子类,它能够计算它读取的字节数。我无法想到标准库中的一个,但实现可能存在于那里 - 然后再次编写自己的很容易。
其他提示
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
*
*/
/**
* @author clint
*
*/
public class ByteCountingInputStream extends FilterInputStream {
public int totalRead = 0;
/**
* @param in
*/
protected ByteCountingInputStream(InputStream in) {
super(in);
// TODO Auto-generated constructor stub
}
/* (non-Javadoc)
* @see java.io.FilterInputStream#read()
*/
@Override
public int read() throws IOException {
int ret = super.read();
totalRead++;
return ret;
}
/* (non-Javadoc)
* @see java.io.FilterInputStream#read(byte[], int, int)
*/
@Override
public int read(byte[] b, int off, int len) throws IOException {
int ret = super.read(b, off, len);
totalRead += ret;
return ret;
}
/* (non-Javadoc)
* @see java.io.FilterInputStream#read(byte[])
*/
@Override
public int read(byte[] b) throws IOException {
int ret = super.read(b);
totalRead += ret;
return ret;
}
/* (non-Javadoc)
* @see java.io.FilterInputStream#skip(long)
*/
@Override
public long skip(long n) throws IOException {
//What to do?
return super.skip(n);
}
/**
* @return the totalRead
*/
protected int getTotalRead() {
return this.totalRead;
}
}
介于
之间ZipInputStream zis = new ZipInputStream(new ByteCountingInputStream(inputStream));
谢谢你们俩!我刚刚完成了克林特建议的完全准备工作!
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
public class CountingInputStream extends FilterInputStream {
private long totalBytes = 0;
protected CountingInputStream(InputStream in) {
super(in);
}
public int getTotalBytesRead() {
return totalBytes;
}
@Override
public int read() throws IOException {
int byteValue = super.read();
if (byteValue != -1) totalBytes++;
return byteValue;
}
@Override
public int read(byte[] b) throws IOException {
int bytesRead = super.read(b);
if (bytesRead != -1) totalBytes+=bytesRead;
return bytesRead;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int bytesRead = super.read(b,off,len);
if (bytesRead != -1) totalBytes+=bytesRead;
return bytesRead;
}
}
现在我想知道我应该给谁一点“勾选标记”。为...
再次感谢!
这就是我所做的......不需要覆盖任何东西。
ZipInputStream zis = new ZipInputStream(inputStream);
ZipEntry ze;
int totalBytes = inputStream.available();
int totalBytesRead = 0;
while ((ze = zis.getNextEntry()) != null) {
totalBytesRead = totalBytes - inputStream.available();
BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(ze.getName()));
byte[] buffer = new byte[4096];
int i;
while ((i = zis.read(buffer)) != -1) {
outStream.write(buffer,0,i);
}
outStream.close();
}
inputStream.close();
不隶属于 StackOverflow