将XDocument转换为字节数组(并将字节数组转换为XDocument)

Owe*_*wen 5 c# xml bytearray linq-to-xml

我接管了一个以二进制格式在SQL Server中存储大型XML文档的系统.

目前,通过将数据转换为字符串,然后将该字符串转换为字节数组来保存数据.但最近与一些大型XML文档试图转换为字符串时,我得到了内存异常,所以我想跳过这个过程,并从的XDocument直行到一个字节数组.

保存XML的Entity Framework类已经扩展,以便二进制数据可以像这样的字符串访问:

partial class XmlData
{
    public string XmlString { get { return Encoding.UTF8.GetString(XmlBinary); } set { XmlBinary = Encoding.UTF8.GetBytes(value); } }
}
Run Code Online (Sandbox Code Playgroud)

我想进一步扩展类看起来像这样:

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想我几乎已经想出了转换,但是当我使用部分类XmlString方法从数据库中获取XML时,XML总是在最后被切断,总是处于不同的字符数:

var memoryStream = new MemoryStream();
var xmlWriter = XmlWriter.Create(memoryStream);
myXDocument.WriteTo(xmlWriter);
XmlData.XmlBinary = memoryStream.ToArray();
Run Code Online (Sandbox Code Playgroud)

这是基本的转换:

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();
}
Run Code Online (Sandbox Code Playgroud)

但由于某些原因,在这个过程中,一些奇怪的非ascii字符被添加到XML中,因此使用我之前的XmlString方法将加载那些奇怪的字符并且XDocument.Parse()会中断,所以我的新的partial类看起来像这样:

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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Lan*_*kin 3

这听起来像是在读取或写入期间未刷新流/写入器之一的缓冲区 - 用于using (...)自动关闭、刷新和处置,并检查在完成读/写的所有位置是否已完成.Flush()