2011-03-11 19 views
10

Gzip kod çözme kodumdan bazılarının bozuk verileri algılayamadığını fark ettim. Sorunu Java GZipInputStream sınıfına kadar takip ettiğimi düşünüyorum. Özellikle, tüm akışı tek bir 'okuma' aramasıyla okuduğunuzda, bozuk verilerin bir IOException'ı tetiklemediği anlaşılıyor. Aynı bozuk veriler üzerinde 2 veya daha fazla çağrıda akışı okursanız, bir istisna tetikler.Bu, Java GZipInputStream sınıfındaki bir hata mı?

Bir hata raporu doldurmayı düşünmeden önce burada topluluğun ne düşündüğünü görmek istedim.

DÜZENLEME: Örneğimi değiştirdim çünkü sonuncusu sorunun ne olduğunu anladığım kadar açık bir şekilde göstermedi. Bu yeni örnekte, 10 baytlık bir tampon gziplenmiş, gzipli tamponun bir baytı değiştirilmiş, daha sonra ungziplenmiştir. 'GZipInputStream.read' çağrısı, 10 baytlık bir tampon için beklediğiniz gibi okunan bayt sayısıyla 10 değerini döndürür. Yine de, sıkıştırılmamış arabellek orijinalinden farklıdır (bozulma nedeniyle). Hiçbir istisna atılmaz. Okuduktan sonra 'uygun' demenin, EOF'a ulaşılmış olsaydı, '0' yerine '1' iadesi olduğunu not ettim.

cevapsız Ne:

@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

+1 iyi soru; iyi yazılmış, özlü, özlü, RUNNABLE örneği ile. Bu yüzden bu kadar çabuk bir cevabınız var :-) –

cevap

9

testi karar verdi: Burada

kaynağıdır. gis.read(unzipped) 1 değerini döndürür, bu nedenle yalnızca bir bayt okundu. Şikayet edemezsiniz, derenin sonu değil.

Bir sonraki read(), "Bozuk GZIP fragmanı"'u atar.

Yani her şey yolunda! (ve en azından GZIPInputStream numaralı telefonda hata yok)

+0

+1 Beni bunun üstüne atla :-) En azından ben JDK'da etrafta dolaşmaktan zevk aldım :-) –

+0

Aslında bu kodu gördüğümde ne olacağını% 99 üzerinde gördüm . bayt [] {0,0, -1, -1}, Z_SYNC_FLUSH için işarettir, bu yüzden vurmuş olabileceğini düşündü. – bestsss

+0

Hiç GZIPInputStream kullanmamıştım, bu yüzden onu izlemek zorunda kaldım. Anahtarın, yolsuzluğun vagonda değil, veride olması olduğunu düşünüyorum. Şüphemin nedenini eklemek için yorumu –

İlgili konular