ZipInputStream 不报告*实际*(即压缩)读取的字节

发布于 2024-07-20 07:02:38 字数 955 浏览 1 评论 0原文

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

我正在读取来自 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 中读取了多少字节?

提前致谢!

Love this website! My issue is as follows:

I'm reading a zip file that's coming over a network from an HTTP "PUT" request. The request header tells me that the Content-Length is (say) 1Mb. The following code creates the ZipInputStream, and saves the zip contents to files in the current directory:

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();

When all is said and done, totalBytesRead is equal to about 1.5Mb (depending on compression of the files, could be anything though!). What I'd like to know is if there is a way to find out how many actual bytes have been read from the original inputStream? Both ze.getSize() and ze.getCompressedSize() return -1 for every zipped entry (i.e. it doesn't know). I need this info for a progress bar to show how many bytes of the transmitted zip file have been read off the network.

Suggestions? Should I perhaps subclass ZipInputStream and try to find out how many bytes it's reading from it's wrapped InputStream?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

野生奥特曼 2024-07-27 07:02:38
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;

/**
 * 
 */

/**
 * @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;
  }

}

This goes in between like

ZipInputStream zis = new ZipInputStream(new ByteCountingInputStream(inputStream));
べ繥欢鉨o。 2024-07-27 07:02:38

谢谢你们俩! 我刚刚完成的制作几乎完全符合克林特的建议!

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;
    }
}

现在我想知道我应该给谁这个小“复选标记”......?

再次感谢!

Thank you both! I just finished making pretty much exactly what Clint suggested!

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;
    }
}

Now I wonder who I should give the little "check-mark" to...?

Thanks again!

ˉ厌 2024-07-27 07:02:38

当然,这看起来很合理。

基本上有两种选择:读取所有字节,将它们存储(在内存或文件中),对它们进行计数,然后解压缩它们; 前者似乎效率低下,而后者需要一个 InputStream 的子类,该子类能够计算它读取的字节数。 我想不出标准库中有一个,但实现可能已经存在了——话又说回来,编写自己的实现也很容易。

Sure, that seems reasonable.

There are basically two options: read all the bytes, store them (in memory or a file), count them, then decompress them; or count them as they come in. The former seems inefficient, and the latter will require a subclass of InputStream which has the ability to count the bytes it reads. I can't think of one in the standard library, but implementations probably exist out there - then again it'd be pretty easy to write your own.

旧城空念 2024-07-27 07:02:38

这就是我所做的......不需要覆盖任何东西。

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();

This is what I do... no need to override anything.

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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文