简体   繁体   English

XmlReader-如何在没有System.OutOfMemoryException的情况下读取元素中的很长的字符串

[英]XmlReader - How to read very long string in element without System.OutOfMemoryException

I have to read a file content Base64 string in an element of XML that is returned from an API. 我必须读取从API返回的XML元素中的文件内容Base64字符串。

My problem is this string can be very long, depending on file size. 我的问题是此字符串可能很长,具体取决于文件大小。

At first, I used XmlDocument to read XML. 最初,我使用XmlDocument读取XML。 Now I use XmlReader to avoid System.OutOfMemoryException when XML is too large. 现在,当XML太大时,我使用XmlReader来避免System.OutOfMemoryException

But I when I read the string, receive a System.OutOfMemoryException too. 但是我在读取字符串时也收到了System.OutOfMemoryException The string is too long, I guess. 我猜这串太长了。

using (XmlReader reader = Response.ResponseXmlXmlReader)
{
    bool found = false;
    //Read result
    while (reader.Read() && !found)
    {
        if(reader.NodeType == XmlNodeType.Element && reader.Name == "content")
        {
            //Read file content
            string file_content = reader.ReadElementContentAsString();
            //Write file
            File.WriteAllBytes(savepath + file.name, Convert.FromBase64String(file_content));

            //Set Found!
            found = true;
        }
    }
} 

How can I read file content string with XmlReader without System.OutOfMemoryException ? 如何在没有System.OutOfMemoryException情况下使用XmlReader读取文件内容字符串?

You can use XmlReader.ReadElementContentAsBase64(Byte[] buffer, Int32 index, Int32 count) for this purpose. 为此XmlReader.ReadElementContentAsBase64(Byte[] buffer, Int32 index, Int32 count)可以使用XmlReader.ReadElementContentAsBase64(Byte[] buffer, Int32 index, Int32 count) This method allows for Base64 element contents of an XML element to be read and decoded in chunks, thus avoiding an OutOfMemoryException for large elements. 此方法允许以块的形式读取和解码XML元素的Base64元素内容,从而避免大型元素出现OutOfMemoryException

For instance, you could introduce the following extension methods: 例如,您可以引入以下扩展方法:

public static class XmlReaderExtensions
{
    public static bool ReadToAndCopyBase64ElementContentsToFile(this XmlReader reader, string localName, string namespaceURI, string path)
    {
        if (!reader.ReadToFollowing(localName, namespaceURI))
            return false;
        return reader.CopyBase64ElementContentsToFile(path);
    }

    public static bool CopyBase64ElementContentsToFile(this XmlReader reader, string path)
    {
        using (var stream = File.Create(path))
        {
            byte[] buffer = new byte[8192];
            int readBytes = 0;

            while ((readBytes = reader.ReadElementContentAsBase64(buffer, 0, buffer.Length)) > 0)
            {
                stream.Write(buffer, 0, readBytes);
            }
        }
        return true;
    }
}

And then do: 然后执行:

var path = Path.Combine(savepath, file.name);
var found = reader.ReadToAndCopyBase64ElementContentsToFile("content", "", path);

Demo fiddle here . 演示在这里摆弄。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM