![](/img/trans.png)
[英]Unable to load file with file size more than 20MB even though maxFilesize is set to 500 in DropZone
[英]Reading XML File ( File size > 500 MB)
我正在尝试解析大型XML文件(大小约为600MB)并使用
这需要更长的时间,最后整个过程被中止。 该过程以异常结束。
消息: “线程被中止”
方法:
private string ReadXml(XmlTextReader reader, string fileName)
{
string finalXML = "";
string s1 = "";
try
{
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element: // The node is an element.
s1 += "<" + reader.Name + ">";
break;
case XmlNodeType.Text: //Display the text in each element.
s1 += reader.Value;
break;
case XmlNodeType.EndElement: //Display the end of the element.
s1 += "</" + reader.Name + ">";
break;
}
finalXML = s1;
}
}
catch (Exception ex)
{
Logger.Logger.LogMessage(ex, "File Processing error: " + fileName);
}
reader.Close();
reader.Dispose();
return finalXML;
}
然后阅读和脱盐:
string finalXML = string.Empty;
XmlTextReader reader = new XmlTextReader(unzipfile);
finalXML = await ReadXml(reader, fileName);
var xmlremovenamespae = Helper.RemoveAllNamespaces(finalXML);
XmlParseObjectNew.BizData myxml = new XmlParseObjectNew.BizData();
using (StringReader sr = new StringReader(xmlremovenamespae))
{
XmlSerializer serializer = new XmlSerializer(typeof(XmlParseObjectNew.BizData));
myxml = (XmlParseObjectNew.BizData)serializer.Deserialize(sr);
}
有没有更好的方法来读取和解析大型xml文件? 需要一个建议。
正如Jon Skeet和DiskJunky所提到的那样,问题是您的数据集太大而无法加载到内存中,并且您的代码没有针对此问题进行优化。 因此,为什么各种类都会向您抛出“内存不足异常”。
首先,字符串串联。 由于字符串的工作方式,对多个字符串使用简单的串联(a + b)通常是个坏主意。 我建议在网上查找如何有效地处理字符串连接(例如,Jon Skeet的“有效地连接字符串” )。
但这是对代码的优化,主要问题是您试图加载到内存中的XML文件的绝对大小。 为了处理大型数据集,通常最好是“流式处理”数据,处理数据块而不是整个文件。
由于您没有显示XML的示例,因此我自由地制作了一个简单的示例来说明我的意思。
考虑您具有以下XML:
<root>
<specialelement>
<value1>somevalue</value1>
<value2>somevalue</value2>
</specialelement>
<specialelement>
<value1>someothervalue</value1>
<value2>someothervalue</value2>
</specialelement>
...
</root>
这个XML的要解析specialelement
为对象,用下面的类定义:
[XmlRoot("specialelement")]
public class ExampleClass
{
[XmlElement(ElementName = "value1")]
public string Value1 { get; set; }
[XmlElement(ElementName = "value2")]
public string Value2 { get; set; }
}
我假设我们可以分别处理每个SpecialElement
,并为此定义一个处理程序,如下所示:
public void HandleElement(ExampleClass item)
{
// Process stuff
}
现在,我们可以使用XmlTextReader
分别读取XML中的每个元素,当我们达到specialelement
我们将跟踪XML元素中包含的数据。 当我们到达specialelement
的末尾时,我们将其反序列化为一个对象,并将其发送给我们的处理程序进行处理。 例如:
using (var reader = new XmlTextReader( /* your inputstream */ ))
{
// Buffer for the element contents
StringBuilder sb = new StringBuilder(1000);
// Read till next node
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
// Clear the stringbuilder when we start with our element
if (string.Equals(reader.Name, "specialelement"))
{
sb.Clear();
}
// Append current element without namespace
sb.Append("<").Append(reader.Name).Append(">");
break;
case XmlNodeType.Text: //Display the text in each element.
sb.Append(reader.Value);
break;
case XmlNodeType.EndElement:
// Append the closure element
sb.Append("</").Append(reader.Name).Append(">");
// Check if we have finished reading our element
if (string.Equals(reader.Name, "specialelement"))
{
// The stringbuilder now contains the entire 'SpecialElement' part
using (TextReader textReader = new StringReader(sb.ToString()))
{
// Deserialize
var deserializedElement = (ExampleClass)serializer.Deserialize(textReader);
// Send to handler
HandleElement(deserializedElement);
}
}
break;
}
}
}
当我们开始处理流中的数据时,我们不必将整个文件加载到内存中。 保持程序的内存使用率较低(防止内存不足异常)。
查看这个小提琴 ,看看它的实际效果。
请注意,这是一个快速示例,仍然有很多地方可以进一步改进和优化此代码。
我尝试这个并且工作正常。
fileName =“您的文件路径”;
试试这个代码,它可以在几秒钟内解析出大于500MB的XML文件。
using (TextReader textReader = new StreamReader(fileName))
{
using (XmlTextReader reader = new XmlTextReader(textReader))
{
reader.Namespaces = false;
XmlSerializer serializer = new XmlSerializer(typeof("YourXmlClassType"));
parseData = ("YourXmlClassType")serializer.Deserialize(reader);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.