2010-11-12 13 views
6

मैं इस JUnit परीक्षण के साथ अटक कर रहा हूँ:क्यों ZipInputStream ZipOutputStream के आउटपुट को नहीं पढ़ सकता है?

public void test() throws Exception { 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    ZipOutputStream zipOut = new ZipOutputStream(out); 
    zipOut.putNextEntry(new ZipEntry("file")); 
    zipOut.write((new byte[] { 0x01, 0x02, 0x03 })); 
    zipOut.closeEntry(); 
    zipOut.close(); 

    ZipInputStream zipIn = new ZipInputStream(new ByteArrayInputStream(out.toByteArray())); 
    ZipEntry entry = zipIn.getNextEntry(); 
    assertNotNull(entry); 
    assertEquals("file", entry.getName()); 
    assertEquals(3, entry.getSize()); 
} 

मैं नाम "फाइल" और एक ZipOutputStream को तीन बाइट्स की एक सामग्री के साथ एक फ़ाइल लिख रहा हूँ। फिर मैं एक ज़िपपूटस्ट्रीम के साथ बनाए गए डेटा को पढ़ने की कोशिश करता हूं, लेकिन अंतिम जोर विफल रहता है, क्योंकि entry.getSize()-1 है और 3 नहीं है, जैसा कि अपेक्षित है।

मैं यहाँ क्या गलत कर रहा हूं? "फ़ाइल" की सामग्री को पुनर्स्थापित करने के लिए मुझे क्या बदलना है? मुझे लगता है, मुझे पहले स्ट्रीम से डेटा पढ़ने में सक्षम होने के लिए लंबाई जाननी है?

+0

अपना कोड आजमाया - वास्तव में यह काम नहीं करता है। मैं परेशान हूँ जांच .. –

+0

समझ गया। नीचे जवाब दें। –

उत्तर

4

आप वास्तव में प्रवेश की सामग्री पढ़ने की है, तो entry.getSize() सही आकार वापस आ जाएगी । यहाँ

byte[] buf = new byte[1024]; 
    int len; 
    while ((len = zipIn.read(buf)) > 0) { 
     // use data; 
    } 
+0

ओह, यह अच्छा है। डेटा पढ़ने के बाद मैं zipEntry के जानकारी फ़ील्ड को देखने से चूक गया ... इस संकेत के लिए धन्यवाद! – tangens

+2

बात यह है कि एक ज़िप प्रविष्टि से पहले एक LOC प्रविष्टि है और एक ज़िप प्रविष्टि के बाद एक EXT प्रविष्टि है। दोनों का आकार क्षेत्र है। ZipOutputStream हमेशा LOC.size में 0 लिखता है, जबकि अन्य संग्रहकर्ता एलओसी के साथ-साथ EXT में आकार लिखते हैं। मुझे आश्चर्य है कि इससे कितनी समस्याएं हो सकती हैं, और ZipOutputStream को एलओसी में आकार कैसे लिखना है? – rustyx

1

मुझे अपने आप से जवाब मिला: entry में सही आकार नहीं है, लेकिन प्रत्येक zipIn.getNextEntry() के साथ आपको अपनी प्रविष्टि की सामग्री को पढ़ने के लिए एक नई स्ट्रीम मिलती है। तो बस अंत तक स्ट्रीम पढ़ें और आपके पास अपनी प्रविष्टि का डेटा है।

मेरी JUnit परीक्षण अंतिम पंक्ति ऐसा दिखाई दे सकता है:

byte[] restoredContent = new byte[ 10 ]; 
assertEquals(3, zipIn.read(restoredContent)); 

अब सब कुछ ठीक काम करता है।

1

ZipEntry के लिए API doc पढ़ें। यह कहता है "अगर ज्ञात"। आप का उपयोग निम्न सामग्री पढ़ सकते हैं (यह सिर्फ zipentry के आकार प्रिंट, बदल यह डेटा की प्रक्रिया उचित रूप से):

ZipEntry entry = zipIn.getNextEntry(); 
int BUFSIZE = 1024; 
byte [] buffer = new byte[BUFSIZE]; 
int read = 0; 
int total = 0; 
while((read = zipIn.read(buffer, 0, BUFSIZE)) >0) { 
    total += read; 
    // what do you want to do with the data read? Do it here 
} 
System.err.println("Total: " + total); 
-1

एक ही समस्या:

प्रविष्टि उपयोग पढ़ने के लिए!

ZipInputStream ZipOutputStream के आउटपुट को नहीं पढ़ सकता है;

नई zipfile (फाइल) एक त्रुटि

कोई संभावित व्याख्या के साथ विफल हो!

पुरालेख दर्शक प्रोग्राम ज़िप फ़ाइल को ठीक ठीक करता है!

समाधान: उह ... यह सब के बाद एक ज़िप फ़ाइल नहीं थी ... यह 'folder.zip' नामक एक टैर था। पुरालेख दर्शक पर्याप्त स्मार्ट था ...

इस समस्या वाले लोगों के लिए: डबल चेक !!!

+2

मुझे खेद है, लेकिन आप किसके बारे में बात कर रहे हैं? आपने ZipOutputStream के साथ एक टीएआर लिखा है ?? – rustyx

0

हाल ही में मुझे ZipOutputStream का उपयोग करके बनाए गए ज़िप बाइट पढ़ने के दौरान एक ही समस्या थी।

निम्नलिखित स्निपेट ने java.lang.NegativeArraySizeException का नेतृत्व किया।

zipEntry = zipInputStream.getNextEntry(); 
byte[] bytes = new byte[(int) zipEntry.getSize()]; 

एक त्वरित समाधान यह अपाचे कॉमन्स-कब IOUtils उपयोग करने के लिए वर्तमान प्रविष्टि के सभी बाइट्स पढ़ने के लिए गया था।

zipEntry = zipInputStream.getNextEntry(); 
byte[] bytes = org.apache.commons.io.IOUtils.toByteArray(zipInputStream); 

मुझे आशा है कि यह किसी के लिए सहायक होगा।

संबंधित मुद्दे