2016-10-17 1 views
0

メモリ不足例外を発生させずに、かなり大きい(〜150 meg)オブジェクトをファイルにシリアル化する方法についての質問に回答しました。それは今働く。今度は、ファイルを逆直列化してオブジェクトに戻す必要があります。ファイルからオブジェクトにdeserializeする - メモリ不足

このコードのバッファ割り当て部分で、メモリ不足エラーが発生しています。私はストリームを手配する方法があると思っていますので、最初に一時的なバッファに読み込む必要はありませんが、助けが必要です。

public static object Deserialize(Type objType, FileInfo xmlDocFile) 
{ 
    object returnValue = null; 
    if (xmlDocFile != null && objType != null && xmlDocFile.Exists) 
    { 
     DataContractSerializer formatter = new DataContractSerializer(objType); 
     ASCIIEncoding encoder = new ASCIIEncoding(); 
     byte[] buffer = null; 
     using (FileStream textFile = new FileStream(xmlDocFile.FullName, FileMode.Open)) 
     { 
      buffer = new byte[textFile.Length]; // Out-of-memory thrown here 
      textFile.Read(buffer, 0, buffer.Length); 
     } 
     XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(buffer, new XmlDictionaryReaderQuotas()); 
     returnValue = formatter.ReadObject(reader, true); 
    } 
    return returnValue; 
} 

私は、オブジェクトをシリアル化するために使用するコードは、この

public static void Serialize(object obj, FileInfo destination) 
{ 
    if (null != obj) 
    { 
     using (TextWriter writer = new StreamWriter(destination.FullName, false)) 
     { 
      XmlTextWriter xmlWriter = null; 
      try 
      { 
       xmlWriter = new XmlTextWriter(writer); 
       DataContractSerializer formatter = new DataContractSerializer(obj.GetType()); 
       formatter.WriteObject(xmlWriter, obj); 
      } 
      finally 
      { 
       if (xmlWriter != null) 
       { 
        xmlWriter.Flush(); 
        xmlWriter.Close(); 
       } 
      } 
     } 
    } 
} 
+0

あなたは、シリアル化メソッドは失敗します、非常に大きなXMLファイルを持っている場合。 xmlreaderを使用してxmlを手動で解析する必要があります。 – jdweng

答えて

1

ファイルをメモリに読み込むする必要はありませんです。ストリームをDataContractSerializerに渡します。

public static object Deserialize(Type objType, FileInfo xmlDocFile) 
{ 
    object returnValue = null; 
    if (xmlDocFile != null && objType != null && xmlDocFile.Exists) 
    { 
     DataContractSerializer formatter = new DataContractSerializer(objType); 

     using (FileStream textFile = new FileStream(xmlDocFile.FullName, FileMode.Open)) 
     { 
      returnValue = formatter.ReadObject(textFile); 
     } 
    } 
    return returnValue; 
} 
+0

XmlDictionaryReaderはどうですか? –

+0

@ jophul - 何のために?複雑にする必要はありません! –

0

(ペトロフずつに非常に近い)私が思いついた解決策は以下のとおりです。

public static object Deserialize(Type objType, FileInfo xmlDocFile) 
{ 
    object returnValue = null;    
    if (xmlDocFile != null && objType != null && xmlDocFile.Exists) 
    { 
     DataContractSerializer formatter = new DataContractSerializer(objType); 
     using (FileStream fs = File.Open(xmlDocFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
     { 
      using (BufferedStream bs = new BufferedStream(fs)) 
      { 
       XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(bs, Encoding.UTF8, new XmlDictionaryReaderQuotas(), null); 
       returnValue = formatter.ReadObject(reader, true); 
      } 
     } 
    } 

    return returnValue; 
}