2011-12-29 2 views
4

OutOfMemoryExceptionがスローされたときに、次の行でxmlファイルが破損し、長さxmlがゼロになることがあります。ファイルの破損を防ぐには?型 'System.OutOfMemoryExceptionに' のxmlファイルを保存するときにファイルが破損しないようにする

xmlDoc.Save(filename) 

保存-例外がスローされました。 System.IO.StreamWriter.Flush(Boolean flushStream、Boolean flushEncoder)、System.IO.StreamWriter.Write(Char(char flushStream、Boolean flushStream、Boolean flushEncoder))での保存時のSystem.IO.FileStream.Write(Byte []配列、Int32オフセット、Int32 カウント) System.Xml.XmlTextWriter.WriteStartElement(文字列の接頭辞で System.Xml.XmlTextWriter.AutoComplete(トークントークン)で System.Xml.XmlTextWriter.Indent(ブールbeforeEndElement)での値)、文字列 ローカル名、ストリングNS) でSystem.Xml.XmlElement.WriteTo(XmlWriter w)のSystem.Xml.XmlDOMTextWriter.WriteStartElement(String接頭辞、String localName、String ns) at System.Xml.XmlElement.WriteContentTo(XmlWriter w) System.Xml.XmlElement .WriteTo(XmlWriter w) MainOptions.SaveでSystem.Xml.XmlDocument.Save(文字列のファイル名)で System.Xml.XmlDocument.WriteTo(たXmlWriter W)でSystem.Xml.XmlDocument.WriteContentTo(たXmlWriterのXW)(文字列のファイル名、ItemOptionsオプション)

+0

それは、そのようなあなたは、ドキュメントのサイズなどの要因の数に依存します保存しようとしているか、エラーがあるかどうかを確認します。あなたが私たちに示したものに基づいてあなたに伝えることはできません。保存しようとしているコードとXMLを表示する必要があります。 –

+0

ファイルは5KBほど大きくなく、アイテムオプションの更新により頻繁に保存されます。個々のオプションの更新でエラーが発生しても、ファイルが破損することはありません。保存中にエラーが発生するだけです。 – walter

+0

前のコピーまたはエラー自体を上書きしないようにしますか? – Matten

答えて

6

ファイルをfilenameに上書きすると上書きされます。バックアップするには 古いコピー、別の場所(のようなfilename.bak)へ

  • 動き、それを保存する前と 別のファイル(のようなfilename.new)などの新しいファイルを保存し、その後または
  • それを削除し、それを名前を変更例外がスローされたときに成功

は、あなたが簡単にxmlファイルの古い/以前のバージョンを復元することができます。

1

OutOfMemory Exception

内部目的または新しいオブジェクトインスタンスに割り当てる十分なメモリがない場合に、この例外は、共通言語ランタイムによってスローすることができます。この例外を回避するには、は、64KB以上のメモリを消費する大きなメソッドのプログラミングを避けてください。

XML文書を保存する方法が考えられる理由の1つは、64KBを超える割り当てを試みているためです。

腐敗を避けるためには、「マッテン」の回答も十分です。ジョン・スカートも同様のことを示唆していますhere

しかし、この操作

private static readonly object locker = new object(); 

    public static void OnlyOneCallerAllowed() 
    { 
    lock (locker) 
    { 
    string tempFileName = System.IO.Path.GetTempFileName(); 
    xmlDoc.Save(tempFileName); 
    File.Move(original_file, original_file.old); 
    File.Move(tempFileName,original_file); 
    File.Delete(tempFileName); 
    } 
    } 
+0

64キロバイト?あなたがインターネットで読んだすべてを信じてはいけません! 64kの制限がある場合、_allocation_にはありません。 –

+0

@JasonWilliamsのフェアポイント、MSDNが嘘をついていることをどのように証明できますか?)次に、コミュニティコンテンツのMSDNにデータを掲載することができます。 –

0

のOutOfMemory例外への対処をしながら、私はロックを使用することにより、さらに安全性のチェックを追加するようになる...

あなたが大きく、数を行く子要素を持つ文書場合レベルが深くなると、インデントがファイルサイズを膨らませる可能性があります。私はスペースを使用してXmlTextWriterインデントでXmlDocumentを見つけました。http://msdn.microsoft.com/en-us/library/system.xml.xmltextwriter.formatting%28v=vs.71%29.aspx

は、すべてのインデントを無効にしてみてくださいし、このことができますかどうかを確認:私は

参照をしました。 1文字のインデントとファイルの再構築を考慮する場合。

+0

はい、そうです。しかし、それはもっと大きな作業の一部です(OutOfMemory例外の解決) – walter

2

Mattenと一致します。代替ソリューションは、ファイルに保存する前に、XML文字列を生成することができます:xmlDoc.Saveに一致するように

Using ms As New MemoryStream 
    xmlDoc.Save(ms) 
    Using outStream As FileStream = File.Open(filename, 
       FileMode.Create, FileAccess.Write, FileShare.Read) 
     ms.WriteTo(outStream) 
    End Using 
End Using 

使用ストリーム(ファイル名)

関連する問題