ZipInputStream은보고하지 않습니다 * 실제 * (예 : 압축) 바이트 읽기

StackOverflow https://stackoverflow.com/questions/826390

  •  05-07-2019
  •  | 
  •  

문제

이 웹 사이트를 사랑하십시오! 내 문제는 다음과 같습니다.

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() ZIPPER 입장마다 -1을 반환합니다 (즉, 모릅니다). 전송 된 ZIP 파일의 바이트가 네트워크에서 읽었는지 표시하려면 진행률 표시 줄 에이 정보가 필요합니다.

제안? ZipInputStream 서브 클래스가 아마도 랩핑 된 입력 스트림에서 읽고있는 바이트 수를 찾아야합니까?

미리 감사드립니다!

도움이 되었습니까?

해결책

물론, 그것은 합리적으로 보입니다.

기본적으로 두 가지 옵션이 있습니다. 모든 바이트를 읽고, 저장 (메모리 또는 파일에)을 저장 한 다음 계산 한 다음 압축을 억제하십시오. 또는 그들이 들어올 때 계산하십시오. 전자는 비효율적 인 것처럼 보이고 후자는 서브 클래스가 필요합니다. 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));

둘 다 감사합니다! 나는 Clint가 제안한 것을 거의 정확히 만들었습니다!

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();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top