Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ZipInputStream不';t报告*实际*(即压缩)字节读取_Java_Inputstream_Unzip - Fatal编程技术网

Java ZipInputStream不';t报告*实际*(即压缩)字节读取

Java ZipInputStream不';t报告*实际*(即压缩)字节读取,java,inputstream,unzip,Java,Inputstream,Unzip,爱这个网站!我的问题如下: 我正在读取一个从HTTP“PUT”请求通过网络发送的zip文件。请求头告诉我内容长度是(比如)1Mb。以下代码创建ZipInputStream,并将zip内容保存到当前目录中的文件中: ZipInputStream zis = new ZipInputStream(inputStream); ZipEntry ze; long totalBytesRead = 0; while ((ze = zis.getNextEntry()) != null) { Buf

爱这个网站!我的问题如下:

我正在读取一个从HTTP“PUT”请求通过网络发送的zip文件。请求头告诉我内容长度是(比如)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();

为什么构造函数受保护?在当前条目数据达到EOF后返回0,否则始终返回1。程序不应依赖此方法返回可以在不阻塞的情况下读取的实际字节数。