我注意到我的一些gzip解碼代碼似乎無法檢測到損壞的數據。我認爲我已經將問題追溯到Java GZipInputStream類。特別是,當你用單個「讀取」調用讀取整個流時,損壞的數據不會觸發IOException。如果您在兩次或多次調用中讀取了同一個已損壞數據的流,則會觸發異常。這是Java GZipInputStream類中的錯誤嗎?
我想看看社區在考慮提交bug報告之前想到了什麼。
編輯:我修改了我的例子,因爲最後一個沒有清楚地說明我認爲是什麼問題。在這個新例子中,一個10字節的緩衝區被壓縮,一個被壓縮的緩衝區的一個字節被修改,然後它被解壓縮。對'GZipInputStream.read'的調用返回10作爲讀取的字節數,這是您對10字節緩衝區的期望值。儘管如此,解壓縮緩衝區與原始緩衝區不同(由於損壞)。沒有例外被拋出。我確實注意到在讀取之後調用'available'會返回'1',而不是'0',如果EOF已經達到,它將會返回。
這裏是源:
@Test public void gzip() {
try {
int length = 10;
byte[] bytes = new byte[]{12, 19, 111, 14, -76, 34, 60, -43, -91, 101};
System.out.println(Arrays.toString(bytes));
//Gzip the byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gos = new GZIPOutputStream(baos);
gos.write(bytes);
gos.finish();
byte[] zipped = baos.toByteArray();
//Alter one byte of the gzipped array.
//This should be detected by gzip crc-32 checksum
zipped[15] = (byte)(0);
//Unzip the modified array
ByteArrayInputStream bais = new ByteArrayInputStream(zipped);
GZIPInputStream gis = new GZIPInputStream(bais);
byte[] unzipped = new byte[length];
int numRead = gis.read(unzipped);
System.out.println("NumRead: " + numRead);
System.out.println("Available: " + gis.available());
//The unzipped array is now [12, 19, 111, 14, -80, 0, 0, 0, 10, -118].
//No IOException was thrown.
System.out.println(Arrays.toString(unzipped));
//Assert that the input and unzipped arrays are equal (they aren't)
org.junit.Assert.assertArrayEquals(unzipped, bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
+1好問題;寫得很好,帶有自包含,簡潔的RUNNABLE示例。這就是爲什麼你得到這樣一個快速答案:-) – 2011-03-11 18:26:03