2010-11-10 14 views
5

हम यह निर्धारित करने एक इनकमिंग InputStream एक ज़िप फ़ाइल या ज़िप डेटा के लिए एक संदर्भ है कि क्या एक आवश्यकता है। हमारे पास स्ट्रीम के अंतर्निहित स्रोत का संदर्भ नहीं है। हमारा उद्देश्य इस धारा की सामग्री को एक वैकल्पिक स्थान पर निर्देशित आउटपुटस्ट्रीम में कॉपी करना है।यह देखना कि धारा एक ज़िप फ़ाइल

मैं धारा ZipInputStream का उपयोग कर और एक ZipEntry निकालने पढ़ने की कोशिश की। यदि धारा एक नियमित रूप से फ़ाइल है ZipEntry रिक्त है - के रूप में उम्मीद - हालांकि, मैं बाइट्स की प्रारंभिक जोड़ी धारा से ढीला एक ZipEntry के लिए जाँच में। इसलिए, जब तक मुझे पता है कि स्ट्रीम एक नियमित धारा है, मैंने स्ट्रीम से शुरुआती डेटा खो दिया है।

अगर InputStream डेटा हानि के बिना एक संग्रह मददगार होगा है, इसकी जांच करने के आसपास किसी भी विचार।

धन्यवाद।

+0

कृपया नीचे गैलेक्टस द्वारा दिए गए उत्तर में मेरी टिप्पणियां देखें - जो दृष्टिकोण मैं संकल्प के रूप में ले रहा हूं। सबको शुक्रीया। – AKS

+1

स्टैक ओवरफ़्लो में आपका स्वागत है! आपके द्वारा चुने गए उत्तर को "चयनित" (बाईं ओर चेक मार्क रूपरेखा) के रूप में चिह्नित करना न भूलें। –

+0

धन्यवाद। अभी किया। – AKS

उत्तर

6

मान लिया जाये कि अपने मूल InputStream बफ़र नहीं है, मैं एक BufferedInputStream में मूल धारा लपेटकर, कि एक ZipInputStream में जांच करने के लिए लपेटकर से पहले की कोशिश करेंगे। आप चेक के बाद स्ट्रीम में प्रारंभिक स्थिति पर वापस जाने के लिए BufferedInputStream में "चिह्न" और "रीसेट" का उपयोग कर सकते हैं।

+0

धन्यवाद। मैं 'दुह!' जा रहा हूँ। मैं यह कोशिश करने जा रहा हूँ। – AKS

+0

यह काम करता है। मैं एक BufferedInputStream के रूप में अपने मूल InputStream लपेट, एक निशान सेट और फिर एक ZipEntry के लिए जाँच करने के लिए एक ZipInputStream बनाने के लिए कर रहा हूँ। एक रीसेट() कॉल और मेरी स्ट्रीम पुन: उपयोग के लिए तैयार है। अब, बफर के लिए सबसे अच्छे आकार के साथ प्रयोग कर रहे हैं। बहुत धन्यवाद ! – AKS

0

यह एक हैक की तरह एक सा लगता है, लेकिन आप ZipInputStream और धारा आप मूल रूप से ZipInputStream के निर्माता के लिए पारित के बीच बैठने के लिए एक प्रॉक्सी java.io.InputStream को लागू कर सकते हैं। आपका प्रॉक्सी एक बफर पर स्ट्रीम करेगा जब तक आप यह नहीं जानते कि यह एक ज़िप फ़ाइल है या नहीं। यदि नहीं, तो बफर आपका दिन बचाता है।

+0

हां, यह एक हैक की तरह लगता है :) .. लेकिन एक दिलचस्प है। मैं गैलेक्टस द्वारा सुझाव का प्रयास करने जा रहा हूं और अगर यह काम नहीं करता है तो इसे आजमाएं :) – AKS

0

आप का वर्णन किया है एक java.io.PushbackInputStream - read() के अलावा, यह एक unread(byte[]) आप उन्हें धारा के सामने से BCK धक्का, और read() उन्हें फिर से फिर से करने की अनुमति देता है है।

यह जेडीके 1.0 के बाद java.io में है (हालांकि मैं स्वीकार करता हूं कि मैंने आज तक इसका उपयोग नहीं देखा है)।

+0

मैंने पुशबैक इनपुट स्ट्रीम का उपयोग करने का प्रयास किया था। जो बिना पढ़े() कॉल करने के लिए खो रहे हैं - हालांकि, एक ZipInputStream बनाने का कार्य करता है, तो धारा एक ZipEntry है और इसलिए एक संग्रह है, पुशबैक धारा के पढ़ने के अलावा बाइट्स पढ़ता जाँच करने के लिए। – AKS

+0

@AKS: रुको, तो आप ZS में पीबीएस लपेट नहीं कर सकते? पराजय इस तरह का पीबीएस की उपयोगिता :( – Piskvor

2

आप ज़िप स्थानीय हैडर हस्ताक्षर (पी 0x03 0x04) के लिए धारा के पहले बाइट की जांच कर सकते हैं, कि ज्यादातर मामलों के लिए पर्याप्त होगा। यदि आपको अधिक सटीकता की आवश्यकता है, तो आपको अंतिम ~ 100 बाइट्स लेना चाहिए और केंद्रीय निर्देशिका लोकेटर फ़ील्ड की जांच करनी चाहिए।

+0

हाँ, इस धारा के सत्यापन के लिए सबसे स्पष्ट दृष्टिकोण होने लगते था।हालांकि, मैं समझता हूं, ज़िप बनाने के लिए उपयोग किए गए टूल के आधार पर, हेडर भिन्न हो सकता है। इसलिए, हालांकि सबसे विश्वसनीय जांच, हम इससे दूर चले गए क्योंकि हम हर संभव pkzip शीर्षलेख की जांच नहीं करना चाहते थे। – AKS

+0

कृपया मुझे बताएं कि उपकरण पर आधारित हेडर में अंतर मामला नहीं है। – AKS

+2

ज़िप मानक ज़िप स्थानीय हेडर फ़ील्ड के लिए एक मजबूत मानदंड है, इसलिए इसमें सभी ज़िप अभिलेखागार के लिए एक ही प्रारूप होना चाहिए। –

2

इस तरह मैंने किया है।

धारा बहाल करने के लिए करता है, तो GZIPInputStream का पता लगाता है गलत ज़िप प्रारूप (ZipException फेंकता) मार्क/रीसेट का उपयोग करना।

/** 
* Wraps the input stream with GZIPInputStream if needed. 
* @param inputStream 
* @return 
* @throws IOException 
*/ 
private InputStream wrapIfZip(InputStream inputStream) throws IOException { 
    if (!inputStream.markSupported()) { 
     inputStream = new BufferedInputStream(inputStream); 
    } 
    inputStream.mark(1000); 
    try { 
     return new GZIPInputStream(inputStream); 
    } catch (ZipException e) { 
     inputStream.reset(); 
     return inputStream; 
    } 
} 
संबंधित मुद्दे