I have to read a file content Base64 string in an element of XML that is returned from an API.
My problem is this string can be very long, depending on file size.
At first, I used XmlDocument
to read XML. Now I use XmlReader
to avoid System.OutOfMemoryException
when XML is too large.
But I when I read the string, receive a System.OutOfMemoryException
too. 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
?
You can use XmlReader.ReadElementContentAsBase64(Byte[] buffer, Int32 index, Int32 count)
for this purpose. 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.
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 .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.