将XDocument转换为字节数组(以及将字节数组转换为XDocument)

6
我接手了一个将大型XML文档以二进制格式存储在SQL Server中的系统。
目前,数据是通过将其转换为字符串,然后将该字符串转换为字节数组来保存的。但最近遇到一些大型XML文档时,在尝试转换为字符串时出现了内存不足异常,因此我想跳过此过程,直接从XDocument转换为字节数组。
扩展了XML的Entity Framework类,使得可以像这样访问二进制数据的字符串:
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();
}

但出于某种原因,在这个过程中,一些奇怪的非ASCII字符被添加到XML中,因此使用我以前的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();
            }
        }
    }
}

2
听起来像是一个流或写入器中的缓冲区在读取或写入期间没有被刷新 - 使用 using (...) 进行自动关闭、刷新和处理,以及检查在您完成读取/写入的所有地方是否已执行 .Flush() - Lanorkin
就是这样了!请添加答案,我会接受它的。 - Owen
1个回答

3

这似乎是在读写期间某个流/写入器的缓冲区未被清空 - 使用 using (...) 进行自动关闭、刷新和释放,同时检查所有完成读取/写入的地方是否都进行了.Flush()操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接