https://stackoverflow.com/questions/54126687/xmlreader-how-to-read-very-long-string-in-element-without-system-outofmemoryex

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Xml.Serialization;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.Data;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO.Compression;

using NUnit.Framework; //NUnit.Framework.AssertionException

    //https://stackoverflow.com/questions/54126687/xmlreader-how-to-read-very-long-string-in-element-without-system-outofmemoryex

    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;
        }
    }
	
	public class Container
	{
		public byte [] content;
	}

	public class RootObject
	{
		public string header;
		public Container container;
	}

	public class TestClass
    {
        public static void Test()
        {
			var fileName = "content.bin";
			var savepath = "";
			var file = new { name = fileName };
			
			var root = new RootObject
			{
				header = "header",
				container = new Container { content = Enumerable.Range(0, 30000).Select(i => unchecked((byte)i)).ToArray() },
			};
			
			var xml = root.GetXml();
			
			using (var sr = new StringReader(xml))
			using (var reader = XmlReader.Create(sr))
			{
				var path = Path.Combine(savepath, file.name);
				var found = reader.ReadToAndCopyBase64ElementContentsToFile("content", "", path);
			}
			
			var bytes = File.ReadAllBytes(fileName);
			
			Assert.IsTrue(bytes.SequenceEqual(root.container.content));
			
			File.Delete(fileName);
        }
    }

    public static class XmlSerializationHelper
    {
        public static T LoadFromXml<T>(this string xmlString, XmlSerializer serial = null)
        {
            serial = serial ?? new XmlSerializer(typeof(T));
            using (var reader = new StringReader(xmlString))
            {
				return (T)serial.Deserialize(reader);
            }
        }

        public static string GetXml<T>(this T obj, bool omitStandardNamespaces)
        {
			return obj.GetXml(null, omitStandardNamespaces);
        }
		
        public static string GetXml<T>(this T obj, XmlSerializer serializer = null, bool omitStandardNamespaces = false)
        {
            XmlSerializerNamespaces ns = null;
            if (omitStandardNamespaces)
            {
                ns = new XmlSerializerNamespaces();
                ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
            }			
            using (var textWriter = new StringWriter())
            {
                var settings = new XmlWriterSettings() { Indent = true }; // For cosmetic purposes.
                using (var xmlWriter = XmlWriter.Create(textWriter, settings))
                    (serializer ?? new XmlSerializer(obj.GetType())).Serialize(xmlWriter, obj, ns);
                return textWriter.ToString();
            }
        }
		
		public static string GetOuterXml(this XmlNode node, bool indent = true)
		{
			if (node == null)
				return null;
			using (var textWriter = new StringWriter())
			{
				var settings = new XmlWriterSettings
				{
					Indent = indent,
					OmitXmlDeclaration = true,
				};
				using (var xmlWriter = XmlWriter.Create(textWriter, settings))
				{
					node.WriteTo(xmlWriter);
				}
				return textWriter.ToString();
			}
		}
    }
				
    public static class XmlAssert
    {
        // https://weblogs.asp.net/marianor/easy-way-to-compare-two-xmls-for-equality
        // https://stackoverflow.com/questions/7318157/best-way-to-compare-xelement-objects
        // Adapted from the answer https://stackoverflow.com/a/14463137 by https://stackoverflow.com/users/1102100/robjohnson
        public static void AreEqual(
            XElement expected,
            XElement actual)
        {
            Assert.IsTrue(XNode.DeepEquals(Normalize(expected), Normalize(actual)));
        }

        private static XElement Normalize(XElement element)
        {
            if (element.HasElements)
            {
                return new XElement(
                    element.Name,
                    element.Attributes()
                           .OrderBy(a => a.Name.ToString()),
                    element.Elements()
                           .OrderBy(a => a.Name.ToString())
                           .Select(e => Normalize(e)));

            }

            if (element.IsEmpty)
            {
                return new XElement(
                    element.Name,
                    element.Attributes()
                           .OrderBy(a => a.Name.ToString()));
            }

            return new XElement(element.Name, element.Attributes()
                .OrderBy(a => a.Name.ToString()), element.Value);
        }
    }
						
	public class Program
	{
		public static void Main()
		{
			Console.WriteLine("Roslyn 2.0 Compiler; Environment version: " + Environment.Version);
			Console.WriteLine();

			try
			{
				TestClass.Test();
			}
			catch (Exception ex)
			{
				Console.WriteLine("Uncaught exception: ");
				Console.WriteLine(ex);
				throw;
			}
		}
	}
;