2011-12-29 4 views
4

Следующая строка иногда развращает файл xml и создает нулевой размер xml, когда выбрано OutOfMemoryException. Как предотвратить повреждение файлов?Предотвращение искажения файлов при сохранении xml-файла

xmlDoc.Save(filename) 

Save-Exception типа 'System.OutOfMemoryException' был брошен. Сохранить в System.IO.FileStream.Write (байт [] массив, смещение Int32, Int32 count) в System.IO.StreamWriter.Flush (Boolean flushStream, Boolean flushEncoder) в System.IO.StreamWriter.Write (Char значение) при System.Xml.XmlTextWriter.Indent (Boolean beforeEndElement) при System.Xml.XmlTextWriter.AutoComplete (маркер маркера) в System.Xml.XmlTextWriter.WriteStartElement (префикс String, String LocalName, String нс) при System.Xml.XmlDOMTextWriter.WriteStartElement (Строка префикса, строка LocalName, String нс) при System.Xml.XmlElement.WriteTo (XmlWriter ш) в System.Xml.XmlElement.WriteContentTo (XmlWriter Вт) при System.Xml.XmlElement .WriteTo (XmlWriter w) в System.Xml.XmlDocument.WriteContentTo (XmlWriter XW) в System.Xml.XmlDocument.WriteTo (XmlWriter ш) в System.Xml.XmlDocument.Save (String имя файла) в MainOptions.Save (Строка файла, параметры ItemOptions)

+0

Это зависит от целого ряда факторов, таких как размер документа, который вы попытка сохранить или имеет ли он ошибки или нет. Мы не можем сказать вам, основываясь на том, что вы нам показали. Вам нужно будет показать нам код и XML, которые вы пытаетесь сохранить. –

+0

Файл не такой большой 5Kb и часто сохраняется из-за обновлений опций элементов; ошибка с отдельными обновлениями не приведет к повреждению файла; только ошибка во время сохранения сделает это – walter

+0

Что вы хотите предотвратить, перезаписать предыдущую копию или ошибку? – Matten

ответ

6

Вы перезаписываете файл при сохранении его на filename. Чтобы создать резервную копию старой копии,

  • переместить его в другое место (например, filename.bak) перед сохранением и удалить его после или
  • сохранить новый файл в другой файл (например, filename.new) и переименовать его на success

Когда вы выбрали исключение, вы можете легко восстановить старую/предыдущую версию xml-файла.

1

OutOfMemory Exception

Это исключение может быть выброшен в общеязыковой среде выполнения, когда не хватает памяти, чтобы выделить для внутренних целей или новых экземпляров объектов. Чтобы избежать этого исключения, избегайте программирования больших методов, которые потребляют 64 или более килобайт памяти.

Таким образом, одной возможной причиной может быть метод, в котором вы сохраняете свой XML-документ, пытается выделить более 64 КБ.

Чтобы избежать коррупции, ответ «Маттен» достаточно хорош, и Джон skeet предлагает то же самое 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 исключение ...

Если документ большой и имеет дочерние элементы, идущие несколько уровней, то отступы могут раздувать размер файла. Я обнаружил, что XmlDocument с отступом XmlTextWriter использует пробелы.Я

См: http://msdn.microsoft.com/en-us/library/system.xml.xmltextwriter.formatting%28v=vs.71%29.aspx

Попробуйте отключить все отступы и посмотреть, если это помогает. Если он рассмотрит 1 отступы и реструктуризацию файла.

+0

Да, вы правы, что должно сэкономить некоторое пространство. Но это часть более масштабной работы (решение исключения OutOfMemory) – walter

2

Согласен с Matten. Альтернативное решение может быть генерации XML-строку перед сохранением в файл:

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 

Используйте поток, чтобы соответствовать xmlDoc.Save (имя файла)

Смежные вопросы