2012-08-16 19 views
10

की पहचान करें मैं वर्तमान में मेरी ज़िप फ़ाइल प्रविष्टियों को संभालने के लिए SharpZip एपीआई का उपयोग कर रहा हूं। यह ज़िप और अनजिपिंग के लिए शानदार काम करता है। हालांकि, मुझे यह पहचानने में समस्या हो रही है कि फ़ाइल एक ज़िप है या नहीं। मुझे यह जानने की ज़रूरत है कि फ़ाइल स्ट्रीम को डिकंप्रेसर किया जा सकता है या नहीं। मूल रूप से मैंनेसी # .नेट ज़िप फ़ाइल

FileStream lFileStreamIn = File.OpenRead(mSourceFile); 
lZipFile = new ZipFile(lFileStreamIn); 
ZipInputStream lZipStreamTester = new ZipInputStream(lFileStreamIn, mBufferSize);// not working 
lZipStreamTester.Read(lBuffer, 0, 0); 
if (lZipStreamTester.CanDecompressEntry) 
{ 

LZipStreamTester हर बार शून्य हो जाता है और यदि कथन विफल हो जाता है। मैंने इसे बफर के साथ/बिना कोशिश की। क्या कोई इस बारे में कोई अंतर्दृष्टि दे सकता है? मुझे पता है कि मैं फ़ाइल एक्सटेंशन की जांच कर सकता हूं। मुझे ऐसा कुछ चाहिए जो उससे अधिक निश्चित है। मुझे यह भी पता है कि ज़िप में एक जादू # (पीके कुछ है), लेकिन यह गारंटी नहीं है कि यह हमेशा वहां रहेगा क्योंकि प्रारूप की आवश्यकता नहीं है।

इसके अलावा मैं के बारे में .net 4.5 देशी ज़िप समर्थन होने तो मेरी परियोजना sharpzip के बजाय कि में माइग्रेट कर सकते हैं पढ़ा लेकिन मैं अभी भी जरूरत है एक विधि/परम यहाँ CanDecompressEntry के समान नहीं देखा: http://msdn.microsoft.com/en-us/library/3z72378a%28v=vs.110%29

मेरे अंतिम उपाय कोशिश करने का प्रयास करें और फ़ाइल पर अनजिप करने का प्रयास करें।

+0

मेरे सवाल का सबसे सरल रूप में इस "उपरोक्त कोड में, क्यों अगर बयान झूठे वापसी है?" है –

उत्तर

5

यह एक घटक के लिए एक बेस क्लास है जिसे असंपीड़ित डेटा को संभालने की आवश्यकता होती है, पीकेजेआईपी संपीड़ित (sharpziplib) या GZip संपीड़ित (.NET में निर्मित)। शायद आपको जरूरत से थोड़ा अधिक लेकिन आपको जाना चाहिए। यह डेटा स्ट्रीम के शीर्षलेख को पार्स करने के लिए @ फोएनिक्यूके के सुझाव का उपयोग करने का एक उदाहरण है। छोटे फैक्ट्री मैथोड में देखे गए व्युत्पन्न वर्गों ने पीकेज़िप और जीजेआईपी डिकंप्रेशन के विनिर्देशों को संभाला।

abstract class Expander 
{ 
    private const int ZIP_LEAD_BYTES = 0x04034b50; 
    private const ushort GZIP_LEAD_BYTES = 0x8b1f; 

    public abstract MemoryStream Expand(Stream stream); 

    internal static bool IsPkZipCompressedData(byte[] data) 
    { 
     Debug.Assert(data != null && data.Length >= 4); 
     // if the first 4 bytes of the array are the ZIP signature then it is compressed data 
     return (BitConverter.ToInt32(data, 0) == ZIP_LEAD_BYTES); 
    } 

    internal static bool IsGZipCompressedData(byte[] data) 
    { 
     Debug.Assert(data != null && data.Length >= 2); 
     // if the first 2 bytes of the array are theG ZIP signature then it is compressed data; 
     return (BitConverter.ToUInt16(data, 0) == GZIP_LEAD_BYTES); 
    } 

    public static bool IsCompressedData(byte[] data) 
    { 
     return IsPkZipCompressedData(data) || IsGZipCompressedData(data); 
    } 

    public static Expander GetExpander(Stream stream) 
    { 
     Debug.Assert(stream != null); 
     Debug.Assert(stream.CanSeek); 
     stream.Seek(0, 0); 

     try 
     { 
      byte[] bytes = new byte[4]; 

      stream.Read(bytes, 0, 4); 

      if (IsGZipCompressedData(bytes)) 
       return new GZipExpander(); 

      if (IsPkZipCompressedData(bytes)) 
       return new ZipExpander(); 

      return new NullExpander(); 
     } 
     finally 
     { 
      stream.Seek(0, 0); // set the stream back to the begining 
     } 
    } 
} 
+0

यह सहायक है लेकिन शोध से मैंने पीके फ़ाइल हेडर किया है या जादू संख्या यह निर्धारित करने का एक विश्वसनीय तरीका नहीं है कि फ़ाइल ज़िप है या नहीं। फिर भी आपका धन्यवाद। –

+1

उसमें कोई दिक्कत नहीं हुई है लेकिन यह एक ऐसी प्रणाली से है जहां संपीड़ित डेटा के स्रोत अच्छी तरह से समझते और नियंत्रित होते हैं। सौभाग्य! – dkackman

+0

मुझे यह सुनिश्चित करने के लिए हमारी फाइल सिस्टम पर ऑडिट करना होगा। मेरा मानना ​​है कि पीके जादू संख्या की जांच, फ़ाइल एक्सटेंशन, और अनजिप पर पकड़ने का प्रयास पर्याप्त होगा। हम मूल रूप से यह निर्धारित करने के लिए प्रयास करें कि फ़ाइल एक ज़िप थी या नहीं, लेकिन इसे वहां होना चाहिए। यहां तक ​​कि अगर हम जादू संख्या पर एक ज़िप मानते हैं तो भी हमें यह निर्धारित करने की कोशिश करनी होगी कि ज़िप दूषित हो गया है या नहीं। काश मैं आपको प्रतिनिधि बना सकता हूं लेकिन अभी भी बहुत कुछ नहीं। हमने यह भी काम किया है कि हम कुछ अस्पष्टता को दूर करने के लिए फाइलें कैसे अपलोड करेंगे। एक बार फिर धन्यवाद। –

7

आप या तो:

  • एक कोशिश पकड़ संरचना का प्रयोग करें और फ़ाइल शीर्षक पार्स को देखने के लिए एक संभावित ज़िप फ़ाइल
  • की संरचना पढ़ने की कोशिश करता है, तो यह एक ज़िप फ़ाइल
है आवेदन/z:

ज़िप फ़ाइलें हमेशा 0x04034b50 अपनी पहली 4 बाइट (http://en.wikipedia.org/wiki/Zip_(file_format)#File_headers)

+0

विकिपीडिया और अन्य स्रोतों ने सूचीबद्ध किया है कि यह निर्धारित करने का एक अच्छा तरीका नहीं है कि फ़ाइल एक ज़िप है या नहीं, क्योंकि ज़िप के फ़ाइल प्रारूप के लिए यह आवश्यक नहीं है। वैकल्पिक रूप से, हम पकड़ने की कोशिश से बचना चाहते हैं लेकिन यह वर्तमान विधि है। –

+1

नोट: 0x04034B50 थोड़ा एंडियन है, इसलिए फ़ाइल का पहला बाइट 0x50 है, दूसरा एक 0x4B है और इसी तरह ... – vojta

2

आप के लिए वेब प्रोग्रामिंग रहे हैं, तो आप जाँच कर सकते हैं फ़ाइल सामग्री प्रकार के रूप में के साथ शुरू आईपी ​​

9

देखें https://stackoverflow.com/a/16587134/206730 संदर्भ

चेक नीचे दिए गए लिंक:

icsharpcode-sharpziplib-validate-zip-file

How-to-check-if-a-file-is-compressed-in-c#

ज़िप फ़ाइलें हमेशा 0x04034b50 (4 बाइट्स) के साथ शुरू
देखें: http://en.wikipedia.org/wiki/Zip_(file_format)#File_headers

नमूना उपयोग:

 bool isPKZip = IOHelper.CheckSignature(pkg, 4, IOHelper.SignatureZip); 
     Assert.IsTrue(isPKZip, "Not ZIP the package : " + pkg); 

// http://blog.somecreativity.com/2008/04/08/how-to-check-if-a-file-is-compressed-in-c/ 
    public static partial class IOHelper 
    { 
     public const string SignatureGzip = "1F-8B-08"; 
     public const string SignatureZip = "50-4B-03-04"; 

     public static bool CheckSignature(string filepath, int signatureSize, string expectedSignature) 
     { 
      if (String.IsNullOrEmpty(filepath)) throw new ArgumentException("Must specify a filepath"); 
      if (String.IsNullOrEmpty(expectedSignature)) throw new ArgumentException("Must specify a value for the expected file signature"); 
      using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
      { 
       if (fs.Length < signatureSize) 
        return false; 
       byte[] signature = new byte[signatureSize]; 
       int bytesRequired = signatureSize; 
       int index = 0; 
       while (bytesRequired > 0) 
       { 
        int bytesRead = fs.Read(signature, index, bytesRequired); 
        bytesRequired -= bytesRead; 
        index += bytesRead; 
       } 
       string actualSignature = BitConverter.ToString(signature); 
       if (actualSignature == expectedSignature) return true; 
       return false; 
      } 
     } 

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