4

このウェブサイトが大好きです!私の問題は次のとおりです。

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 から読み取っているバイト数を確認する必要がありますか?

前もって感謝します!

4

4 に答える 4

2

あなたがた両方に感謝します!クリントが提案したものとほとんど同じものを作り終えました!

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

さて、誰に小さな「チェックマーク」をつけようかな…?

再度、感謝します!

于 2009-05-05T19:26:05.360 に答える
2
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));
于 2009-05-05T19:20:58.667 に答える
1

確かに、それは合理的に思えます。

基本的に 2 つのオプションがあります。すべてのバイトを読み取り、(メモリまたはファイルに) 格納し、カウントしてから解凍します。前者は非効率的で、後者はInputStream読み取るバイト数をカウントする機能を持つサブクラスを必要とします。標準ライブラリには考えられませんが、実装はおそらくそこに存在します。また、独自の実装を作成するのは非常に簡単です。

于 2009-05-05T19:00:21.133 に答える
-1

これが私がしていることです...何も上書きする必要はありません。

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();
于 2012-03-01T14:48:08.327 に答える