Provide accurate InputStream.available() results

Provide accurate InputStream.available() results by using the size
attribute of the ZipEntry. This helps improve performance with
CGLib and also fixes issues where libraries expect that a non-zero
result from available() indicates that read() will not return -1.
This commit is contained in:
Phillip Webb
2013-08-27 01:05:43 -07:00
parent cb7cc3991b
commit 5b7d56895b
2 changed files with 27 additions and 4 deletions

View File

@@ -187,7 +187,7 @@ public class RandomAccessJarFile extends JarFile {
public synchronized InputStream getInputStream(ZipEntry ze) throws IOException {
InputStream inputStream = getData(ze).getInputStream();
if (ze.getMethod() == ZipEntry.DEFLATED) {
inputStream = new ZipInflaterInputStream(inputStream);
inputStream = new ZipInflaterInputStream(inputStream, (int) ze.getSize());
}
return inputStream;
}
@@ -448,15 +448,35 @@ public class RandomAccessJarFile extends JarFile {
}
/**
* {@link InflaterInputStream} that support the writing of an extra "dummy" byte which
* is required with JDK 6
* {@link InflaterInputStream} that supports the writing of an extra "dummy" byte
* (which is required with JDK 6) and returns accurate available() results.
*/
private static class ZipInflaterInputStream extends InflaterInputStream {
private boolean extraBytesWritten;
public ZipInflaterInputStream(InputStream inputStream) {
private int available;
public ZipInflaterInputStream(InputStream inputStream, int size) {
super(inputStream, new Inflater(true), 512);
this.available = size;
}
@Override
public int available() throws IOException {
if (this.available < 0) {
return super.available();
}
return this.available;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int result = super.read(b, off, len);
if (result != -1) {
this.available -= result;
}
return result;
}
@Override
@@ -476,4 +496,5 @@ public class RandomAccessJarFile extends JarFile {
}
}
}

View File

@@ -115,7 +115,9 @@ public class RandomAccessJarFileTests {
public void getInputStream() throws Exception {
InputStream inputStream = this.jarFile.getInputStream(this.jarFile
.getEntry("1.dat"));
assertThat(inputStream.available(), equalTo(1));
assertThat(inputStream.read(), equalTo(1));
assertThat(inputStream.available(), equalTo(0));
assertThat(inputStream.read(), equalTo(-1));
}