2014-07-14 5 views
6

मुझे उन प्रकार की सूची मिली है जिन्हें मुझे फ़ाइल में सहेजने और इसे पढ़ने के बाद की आवश्यकता है। मैं DataContractSerializer का उपयोग, लेकिन मैं अक्रमांकन दौरान एक अपवाद प्राप्त करें:सिस्टम को क्रमबद्ध/deserialize.RuntimeType

तर्कों (SerializationInfo, StreamingContext) ISerializable "System.RuntimeType" में साथ निर्माता नहीं मिल सकी।

मैंने System.RuntimeType को मेरे सीरिएलाइज़र के ज्ञात प्रकार के रूप में जोड़ा है, लेकिन इससे मदद नहीं मिली।

यहाँ मेरी दो तरीकों में से कोड है

public static void SaveTypes(List<Type> types, string fileName) 
{ 
    Type rt = types[0].GetType(); 

    List<Type> knownTypes = new List<Type>() { rt }; //I get a List with System.RuntimeType item here 
    DataContractSerializer serializer = new DataContractSerializer(typeof(List<Type>), knownTypes); 
    XmlWriterSettings settings = new XmlWriterSettings(); 
    settings.Indent = true; 
    Stream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write); 
    using (XmlWriter xw = XmlWriter.Create(fs, settings)) 
     serializer.WriteObject(xw, types); 
} 

क्रमबद्धता ठीक से काम करने लगता है, और आउटपुट फ़ाइल ठीक है, लेकिन समस्या यह deserializing पर शुरू होता है:

public static object LoadTypes(string fileName) 
    { 
     Stream file = new FileStream(fileName, FileMode.Open, FileAccess.Read); 
     byte[] data = new byte[file.Length]; 
     file.Read(data, 0, (int)file.Length); 

     Type rt = file.GetType(); 
     List<Type> knownTypes = new List<Type>() { rt.GetType() }; 
     DataContractSerializer deserializer = new DataContractSerializer(typeof(List<Type>), knownTypes); 

     Stream stream = new MemoryStream(); 
     stream.Write(data, 0, data.Length); 
     stream.Position = 0; 
     return deserializer.ReadObject(stream); //exception here 
    } 

वहाँ के माध्यम से जाना कोई तरीका है इस? या शायद प्रकारों को स्टोर करने का कोई और तरीका है?

+3

आपको ** डेटा ** को क्रमबद्ध करना चाहिए, कार्यान्वयन नहीं। ए 'टाइप' कार्यान्वयन के बारे में 100% है। वाकई, यह जाने का गलत तरीका है, और यह उस अंधेरे रास्ते को आगे बढ़ाने में आपकी मदद करने के लिए एक अक्षमता होगी। IMO। –

+0

मैं डेटा को क्रमबद्ध करता हूं, लेकिन इसमें उपयोगकर्ता परिभाषित प्रकार शामिल हैं जिन्हें मैं एक्सेस नहीं कर सकता। तो जब मैं उन्हें deserialize मैं उन प्रकारों को जानने की जरूरत है। मैंने सोचा कि उन्हें एक्सेस करने का एकमात्र तरीका उन्हें फाइल में स्टोर करना है। –

उत्तर

2

मार्क ग्रेवल सही है, तो संभवतः आपको डेटा को क्रमबद्ध करना चाहिए, न कि प्रकारों।

लेकिन किसी कारण से, यदि आप वास्तव में प्रकारों को क्रमबद्ध करना चाहते हैं, तो आपको टाइप ऑब्जेक्ट को क्रमबद्ध नहीं करना चाहिए (सुनिश्चित करें कि यह serailizable नहीं है)। वैसे भी, Type.FullName क्रमशः serialize। जब आप प्रकार लोड करते हैं, का उपयोग Type.Load

public static void SaveTypes(IEnumerable<Type> types, string filename) 
{ 
    using (var fs = File.Open(filename, FileMode.OpenOrCreate) 
     new XmlSerializer(typeof(string[])) 
      .Serialize(fs, types.Select(t => t.FullName).ToArray()) 
} 

pubic static IEnumerable<Type> LoadTypes(string filename) 
{ 
    using (var fs = File.Open(filename, FileMode.Open) 
    { 
     var typeNames = (string[]) 
      new XmlSerializer(typeof(string[])) 
      .Deserialize(fs); 

      return typeNames.Select(t => Type.Load(t)); 
    } 
} 

नोट: जब किसी भी Stream (या वास्तव में किसी भी IDisposable) के साथ काम कर आप या तो Dispose विधि कॉल या using कथन का उपयोग (जैसा कि मैंने ऊपर किया) किया है। यह सुनिश्चित करता है कि IDisposable ठीक से साफ़ किया गया है (यानी फ़ाइल सिस्टम हैंडल जारी करता है)।

+0

किसी कारण से मुझे Type.Load विधि नहीं मिल रही है। क्या आप वाकई मौजूद हैं? –

+1

वह शायद 'टाइप। एस्परब्स क्वालिफाइडनाम'] (https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname%28v=vs.110%29.aspx) को क्रमबद्ध करने के लिए 'टाइप' के बजाय क्रमबद्ध करना था FullName', ['Type.GetType'] (https://msdn.microsoft.com/en-us/library/w3f99sx1%28v=vs.110%29.aspx) का उपयोग करके प्रकार को लोड करने के लिए, nonexistent' टाइप करें। लोड करें, और शायद ['IDataContractSurrogate'] (https://msdn.microsoft.com/en-us/library/system.runtime.serialization.idatacontractsurrogate%28v=vs.110%29 का उपयोग करने के लिए सुझाव दिया जाना चाहिए था। एएसपीएक्स) क्रमशः क्रमशः/बाद में मूल्यों को प्रतिस्थापित करने के बजाय। – binki

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