#c# #xml #linq-to-xml #bytearray
#c# #xml #linq-to-xml #массивы
Вопрос:
Я перенял систему, которая хранит большие XML-документы в SQL Server в двоичном формате.
В настоящее время данные сохраняются путем преобразования их в строку, а затем преобразования этой строки в массив байтов. Но в последнее время с некоторыми большими XML-документами я получаю исключения из памяти при попытке преобразования в строку, поэтому я хочу обойти этот процесс и перейти прямо из XDocument в массив байтов.
Класс Entity Framework, содержащий XML, был расширен, так что двоичные данные доступны в виде строки, подобной этой:
partial class XmlData
{
public string XmlString { get { return Encoding.UTF8.GetString(XmlBinary); } set { XmlBinary = Encoding.UTF8.GetBytes(value); } }
}
Я хочу еще больше расширить класс, чтобы он выглядел примерно так:
partial class XmlData
{
public string XmlString{ get { return Encoding.UTF8.GetString(XmlBinary); } set { XmlBinary = Encoding.UTF8.GetBytes(value); } }
public XDocument XDoc
{
get
{
// Convert XmlBinary to XDocument
}
set
{
// Convert XDocument to XmlBinary
}
}
}
Я думаю, что я почти разобрался с преобразованием, но когда я использую метод частичных классов XmlString для получения XML обратно из БД, XML всегда обрезается ближе к концу, всегда с другим количеством символов:
var memoryStream = new MemoryStream();
var xmlWriter = XmlWriter.Create(memoryStream);
myXDocument.WriteTo(xmlWriter);
XmlData.XmlBinary = memoryStream.ToArray();
РЕШЕНИЕ
Вот основное преобразование:
var settings = new XmlWriterSettings { OmitXmlDeclaration = true, Encoding = Encoding.UTF8 };
using (var memoryStream = new MemoryStream())
using (var xmlWriter = XmlWriter.Create(memoryStream, settings))
{
myXDocument.WriteTo(xmlWriter);
xmlWriter.Flush();
XmlData.XmlBinary = memoryStream.ToArray();
}
Но по какой-то причине в этом процессе в XML добавляются некоторые странные символы, отличные от ascii, поэтому использование моего предыдущего метода XmlString загрузит эти странные символы и XDocument.Parse() сломается, поэтому мой новый частичный класс выглядит так:
partial class XmlData
{
public string XmlString
{
get
{
var xml = Encoding.UTF8.GetString(XmlBinary);
xml = Regex.Replace(xml, @"[^u0000-u007F]", string.Empty); // Removes non ascii characters
return xml;
}
set
{
value = Regex.Replace(value, @"[^u0000-u007F]", string.Empty); // Removes non ascii characters
XmlBinary = Encoding.UTF8.GetBytes(value);
}
}
public XDocument XDoc
{
get
{
using (var memoryStream = new MemoryStream(XmlBinary))
using (var xmlReader = XmlReader.Create(memoryStream))
{
var xml = XDocument.Load(xmlReader);
return xml;
}
}
set
{
var settings = new XmlWriterSettings { OmitXmlDeclaration = true, Encoding = Encoding.UTF8 };
using (var memoryStream = new MemoryStream())
using (var xmlWriter = XmlWriter.Create(memoryStream, settings))
{
value.WriteTo(xmlWriter);
xmlWriter.Flush();
XmlBinary = memoryStream.ToArray();
}
}
}
}
Комментарии:
1. Похоже, что буфер одного из потоков / записей не был очищен во время чтения или записи — используйте
using (...)
для автоматического закрытия, очистки и удаления, а также проверьте, что во всех местах, где вы закончили чтение / запись, вы сделали.Flush()
2. Вот и все! Продолжайте и добавьте ответ, и я его приму.
Ответ №1:
Похоже, что буфер одного из потоков / записей не был очищен во время чтения или записи — используйте using (...)
для автоматического закрытия, очистки и удаления, а также проверьте, что во всех местах, где вы закончили чтение / запись, вы сделали .Flush()