2010-11-28 8 views
5

के साथ मिलकर मैं किसी ऑब्जेक्ट के कस्टम क्रमबद्धता/deserialization करने के साथ-साथ DeflateStreams के साथ serialized डेटा को संपीड़ित/decompressing करने की कोशिश कर रहा हूँ। मैंने मूल रूप से इसे अधिक जटिल वस्तुओं के लिए किया लेकिन समस्या को हल करने और समझने के लिए इसे काट दिया, हालांकि यह अभी भी और अधिक परेशान हो गया है क्योंकि यह अभी भी वहां है।सी # कस्टम सीरियलाइजेशन/Deserialization DeflateStreams

[Serializable] 
    public class RandomObject : ISerializable 
    { 
     public String Name { get; set; } 
     public String SavePath { get; set; } 

     public RandomObject() 
     { 
     } 

     public RandomObject(String name, String savepath) 
     { 
      Name = name; 
      SavePath = savepath; 
     } 

     public RandomObject(SerializationInfo info, StreamingContext context) 
      : this(info.GetString("name"), info.GetString("savepath")) 
     { 
     } 
     [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] 
     public void GetObjectData(SerializationInfo info, StreamingContext context) 
     { 
      info.AddValue("name", Name); 
      info.AddValue("savepath", SavePath); 
     } 
    } 

यहाँ और कोड है कि यह (जो काम करने के लिए लगता है) को क्रमानुसार ले आते है: यहां है अक्रमांकन

BinaryFormatter bf = new BinaryFormatter(); 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       bf.Serialize(ms, profile); 
       using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Compress)) 
       { 
        try 
        { 
         using (FileStream fs = File.Create(path)) 
         { 
          ds.Flush(); 
          Miscellaneous.CopyStream(ds.BaseStream, fs); 
          fs.Flush(); 
          fs.Close(); 
         } 
        } 
        catch (IOException e) 
        { 
         MessageBox.Show(e.Message); 
         success = false; 
        } 
        ds.Close(); 
       } 
       ms.Close(); 
      } 

और: यहाँ वर्ग धारावाहिक जा करने के लिए/deserialized है

RandomObject profile = null; 
       using (FileStream fs = File.OpenRead(path)) 
       { 
        using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Decompress)) 
        { 
         BinaryFormatter bf = new BinaryFormatter(); 
         ds.Flush(); 

         using (MemoryStream ms = new MemoryStream()) 
         { 
          Miscellaneous.CopyStream(ds.BaseStream, ms); 
          profile = bf.Deserialize(ms) as RandomObject; 
          profile.SavePath = path; 
          ms.Close(); 
         } 
         ds.Close(); 
        } 
        fs.Close(); 
       } 

अब समस्या के लिए। Deserialization संदेश {"ऑब्जेक्ट के लिए कोई नक्शा '201326592' संदेश के साथ एक serializationException फेंकता है।"} मुझे नहीं पता कि समस्या का कारण क्या है समस्या निवारण या पता लगाने के लिए। बहुत ही बुनियादी क्रमबद्धता तब काम करती है जब मैं एक ही मेमोरीस्ट्रीम पर बाइनरीफॉर्मेटर की सीरियल और Deserialize विधियों को चलाता हूं।

मैंने दोनों विधियों से DeflateStream सामान को हटाने का प्रयास किया, लेकिन यह अभी भी वही समस्या है। जब मैं एमएसडीएन और अन्य स्थानों पर उदाहरणों को देखता हूं तो ऐसा लगता है कि मैं इसे सही कर रहा हूं, और अपवाद संदेश के लिए googling कोई सार्थक परिणाम नहीं देता है (या शायद मैं खोज में बस खराब हूँ)।

पीएस। जैसा कि आप देख सकते हैं कि मैं Miscellaneous.CopyStream (src, dest) का उपयोग करता हूं जो मूल स्ट्रीम कॉपीियर है, क्योंकि मुझे src.CopyTo (dest) बिल्कुल काम नहीं मिल सकता है, इसलिए उस पर किसी भी संकेत का स्वागत है।

नीचे यदि आप और अधिक बारीकी से इस पर गौर करना चाहते हैं पूरे VS2010 परियोजना के लिए एक लिंक है: http://www.diredumplings.com/SerializationTesting.zip

अद्यतन:

The_Smallest: मैं कम्प्रेस विधि आप पर पोस्ट उपयोग करने की कोशिश मेरी क्रमबद्धता:

BinaryFormatter bf = new BinaryFormatter(); 
      using (MemoryStream stream = new MemoryStream()) 
      { 
       bf.Serialize(stream, profile); 

       byte[] array = Compress(stream); 

       using (MemoryStream ms = new MemoryStream(array)) 
       { 
        using (FileStream fs = File.Create(path)) 
        { 
         ms.WriteTo(fs); 
         fs.Flush(); 
        } 
       } 
      } 

हालांकि, यह मुझे एक ही समस्या है कि मैंने पहले srcStream.CopyTo (destStream) के साथ किया था देने के लिए लगता है, जो है यह है कि प्रतीत होता है कि स्ट्रीम में लिखा नहीं है। जब मैं इसे डिस्क पर सहेजने का प्रयास करता हूं तो परिणाम 0 केबी फ़ाइल होता है। कोई विचार?

पीटर: मैंने मेमरीस्ट्रीम को deserialization विधि से हटा दिया और ऐसा लगता है कि पहले की तरह ही कार्यक्षमता है। हालांकि मुझे यकीन नहीं है कि आपके द्वारा सुझाए गए क्रमबद्धरण को कैसे कार्यान्वित किया जाए। क्या यह है जो आप के मन में था?

BinaryFormatter bf = new BinaryFormatter(); 

      using (FileStream fs = File.Create(path)) 
      { 
       using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Compress)) 
       { 
        bf.Serialize(ds, profile); 
        fs.Flush(); 
        ds.Close(); 
       } 
       fs.Close(); 
      } 

आप दोनों को धन्यवाद!

+0

और क्या है Stream.Copy के साथ समस्या? यह क्यों विफल रहता है? –

+0

इससे कोई फर्क नहीं पड़ता कि मैं इसका उपयोग कैसे करता हूं गंतव्य स्ट्रीम हमेशा खाली होती है, हो सकता है कि मैं बस कुछ बेवकूफ कर रहा हूं। – vesz

उत्तर

1

मैंने आपको उदाहरण दिया और वहां थोड़ा सा खोद दिया।

  1. Loader.cs में LoadFromFile बदलें
private static RandomObject LoadFromFile(string path) 
{ 
    try 
    { 
    var bf = new BinaryFormatter(); 
    using (var fileStream = File.OpenRead(path)) 
    using (var decompressed = new MemoryStream()) 
    { 
     using (var deflateStream = new DeflateStream(fileStream, CompressionMode.Decompress)) 
     deflateStream.CopyTo(decompressed); 

     decompressed.Seek(0, SeekOrigin.Begin); 
     var profile = (RandomObject)bf.Deserialize(decompressed); 
     profile.SavePath = path; 
     return profile; 
    } 
    } 
    catch (IOException e) 
    { 
    MessageBox.Show(e.Message); 
    return null; 
    } 
} 
 
  1. Saver.cs में Save बदलें इस प्रकार है:: नीचे अपनी परियोजना के लिए परिवर्तन देखें
public static bool Save(RandomObject profile, String path) 
{ 
    try 
    { 
     var bf = new BinaryFormatter(); 
     using (var uncompressed = new MemoryStream()) 
     using (var fileStream = File.Create(path)) 
     { 
     bf.Serialize(uncompressed, profile); 
     uncompressed.Seek(0, SeekOrigin.Begin); 

     using (var deflateStream = new DeflateStream(fileStream, CompressionMode.Compress)) 
      uncompressed.CopyTo(deflateStream); 
     } 
     return true; 
    } 
    catch (IOException e) 
    { 
     MessageBox.Show(e.Message); 
     return false; 
    } 
} 
+0

यह एक और जवाब है, जबकि पिछले जवाब और कोड हर किसी के लिए उपयोगी हो सकता है, सेक या संपीड़न हटाने कुछ) है कि कम से –

+0

देखो की कोशिश कर रहा है, क्योंकि यह @ vesz की परियोजना के लिए विशिष्ट है, एक आकर्षण की तरह काम करता है। अपने दो अलग-अलग उत्तरों को गठबंधन करने की कोशिश कर रहा था लेकिन कुछ भी काम नहीं किया। आपका बहुत बहुत धन्यवाद! – vesz

+0

पहले संपीड़न के साथ समस्या होने में बहुत समय बिताया। तो किसी के समय और नसों को बचाने और बचाने में मदद की। –

1

आपको DeflateStream में क्रमबद्ध करना चाहिए, आधार (MemoryStream) स्ट्रीम नहीं।

क्रमबद्ध करने के लिए: File.Create से शुरू करें। फिर उस स्ट्रीम के आसपास, DeflateStream बनाएं। फिर DefaulteStream पर, अपनी ऑब्जेक्ट्स को क्रमबद्ध करें।

deserializing के लिए: MemoryStream न बनाएं और सीधे DeflateStream से deserialize करें।

मुझे विश्वास है कि MemoryStream जोड़ा गया कोई आवश्यकता नहीं है। यदि आपको फ़ाइल स्ट्रीम से सीधे सीधे पढ़ने/पढ़ने में समस्याएं हैं, तो MemoryStream के बजाय DeflateStream पर लिखने के लिए केवल क्रमबद्ध दिनचर्या बदलें।

इससे आपके मुद्दों को हल करना चाहिए।

+0

मेमोरीस्ट्रीम का कारण यह था कि जैसा कि मैं कह सकता था कि मैं केवल DeflateStream पढ़ सकता हूं, लिख नहीं सकता या इसमें खोज नहीं सकता। मैं धन्यवाद ऊपर परिवर्तन की कोशिश करें और देखें कि यह काम करता है जाएगा। – vesz

+0

मैंने आपके समाधान में प्रश्न में एक अद्यतन पोस्ट किया है, मुझे अभी भी यह सुनिश्चित नहीं है कि यह कैसे काम कर रहा है। आपके उत्तर यद्यपि के लिए धन्यवाद! – vesz

+1

बदलें 'बीएफ। क्रमबद्ध करें (डी। बेसस्ट्रीम, प्रोफाइल); 'बीएफ में। क्रमबद्ध करें (डीएस, प्रोफाइल);'। 'DeflateStream' वह प्रवाह है जिसे आप को फ़्लोट/डिफ्लेट कार्यक्षमता प्राप्त करने के लिए संवाद करना है। आप 'DeflateStream' के आस-पास काम कर रहे हैं और इसके बजाय बेस स्ट्रीम पर लिख रहे हैं। ऐसा लगता है कि आपके पास 'DeflateStream' बिल्कुल नहीं होगा। जब आप 'DeflateStream' के साथ एक स्ट्रीम लपेटते हैं, तो आपको मूल स्ट्रीम को अनदेखा करना चाहिए और इसके बजाय' DeflateStream' का उपयोग करना चाहिए। –

1

धाराओं लॉजिक्स में त्रुटि हुई है, जबकि, आप CompressStream, जो MemoryStream करने के लिए लिखते हैं करने के लिए लिखना चाहिए संपीड़ित इस के बाद आप MemoryStream (CompressStream में नहीं) में परिणाम होगा यहाँ उदाहरण

सेक और संपीड़न हटाने के लिए कैसे बाइट्स
private static byte[] Compress(Stream stream) 
    { 
     using (var resultStream = new MemoryStream()) 
     { 
      using (var gzipStream = new DeflateStream(resultStream, CompressionMode.Compress)) 
       stream.CopyTo(gzipStream); 
      return resultStream.ToArray(); 
     } 
    } 

    private static byte[] Decompress(byte[] bytes) 
    { 
     using (var readStream = new MemoryStream(bytes)) 
     using (var resultStream = new MemoryStream()) 
     { 
      using (var gzipStream = new DeflateStream(readStream, CompressionMode.Decompress)) 
       gzipStream.CopyTo(resultStream); 
      return resultStream.ToArray(); 
     } 
    } 
+0

मैंने आपके समाधान में प्रश्न में एक अद्यतन पोस्ट किया है, मुझे अभी भी यह सुनिश्चित नहीं है कि यह कैसे काम कर रहा है। आपके उत्तर यद्यपि के लिए धन्यवाद! – vesz

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

  • कोई संबंधित समस्या नहीं^_^