通过流读取 Xml 文件的一部分,而不是只读取一个
Read Parts of an Xml File trough Stream instead of only one
所以我一直在为一个项目编写一段旧代码。
我已经设法针对 64 位使用对其进行了优化。
但只有 1 个问题。当使用 XmlSerializer.Deserialize
它中断是因为输入 text/Deserialized 数据太大。 (overflow/exceeds 2gb int 限制)。
我试图找到解决办法,但没有任何答案有帮助。
这是有问题的代码。
if (File.Exists(dir + "/" + fileName))
{
string XmlString = File.ReadAllText(dir + "/" + fileName, Encoding.UTF8);
BXML_LIST deserialized;
using (MemoryStream input = new MemoryStream(Encoding.UTF8.GetBytes(XmlString)))
{
using (XmlTextReader xmlTextReader = new XmlTextReader(input))
{
xmlTextReader.Normalization = false;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(BXML_LIST));
deserialized = (BXML_LIST)xmlSerializer.Deserialize(xmlTextReader);
}
}
xml_list.Add(deserialized);
}
在这里问了很多问题之后,我认为我可以使用一种方法来“拆分”xml 文件(同时保持相同类型的 BXML_LIST)
然后反序列化完成:将其合并以匹配其原始内容,以避免在反序列化整个文件时出现溢出错误。
问题是,我不知道如何实现它。任何帮助或指导都会很棒!
// 编辑 1:
我从另一个站点找到了一段代码,不知道它是否是合并拆分的 xml 文件的可靠方法:
var xml1 = XDocument.Load("file1.xml");
var xml2 = XDocument.Load("file2.xml");
//Combine and remove duplicates
var combinedUnique = xml1.Descendants("AllNodes")
.Union(xml2.Descendants("AllNodes"));
//Combine and keep duplicates
var combinedWithDups = xml1.Descendants("AllNodes")
.Concat(xml2.Descendants("AllNodes"));
你的代码让我毛骨悚然,你在用尽内存方面效率太低了。
string XmlString = File.ReadAllText
- 这里是第一次将整个文件加载到内存中。
Encoding.UTF8.GetBytes(XmlString)
- 这里你第二次为相同的数据花费内存。
new MemoryStream(...)
- 这里你第三次为相同的数据花费内存。
xmlSerializer.Deserialize
- 此处,内存再次用于反序列化数据。但无法摆脱它。
这样写
using (XmlReader xmlReader = XmlReader.Create(dir + "/" + fileName))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(BXML_LIST));
deserialized = (BXML_LIST)xmlSerializer.Deserialize(xmlReader);
}
在这种情况下,xmlSerializer
将使用 xmlReader
在流中分段从文件中读取数据。
也许,这可能足以解决您的问题。
所以我一直在为一个项目编写一段旧代码。 我已经设法针对 64 位使用对其进行了优化。 但只有 1 个问题。当使用 XmlSerializer.Deserialize 它中断是因为输入 text/Deserialized 数据太大。 (overflow/exceeds 2gb int 限制)。
我试图找到解决办法,但没有任何答案有帮助。
这是有问题的代码。
if (File.Exists(dir + "/" + fileName))
{
string XmlString = File.ReadAllText(dir + "/" + fileName, Encoding.UTF8);
BXML_LIST deserialized;
using (MemoryStream input = new MemoryStream(Encoding.UTF8.GetBytes(XmlString)))
{
using (XmlTextReader xmlTextReader = new XmlTextReader(input))
{
xmlTextReader.Normalization = false;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(BXML_LIST));
deserialized = (BXML_LIST)xmlSerializer.Deserialize(xmlTextReader);
}
}
xml_list.Add(deserialized);
}
在这里问了很多问题之后,我认为我可以使用一种方法来“拆分”xml 文件(同时保持相同类型的 BXML_LIST) 然后反序列化完成:将其合并以匹配其原始内容,以避免在反序列化整个文件时出现溢出错误。
问题是,我不知道如何实现它。任何帮助或指导都会很棒!
// 编辑 1:
我从另一个站点找到了一段代码,不知道它是否是合并拆分的 xml 文件的可靠方法:
var xml1 = XDocument.Load("file1.xml");
var xml2 = XDocument.Load("file2.xml");
//Combine and remove duplicates
var combinedUnique = xml1.Descendants("AllNodes")
.Union(xml2.Descendants("AllNodes"));
//Combine and keep duplicates
var combinedWithDups = xml1.Descendants("AllNodes")
.Concat(xml2.Descendants("AllNodes"));
你的代码让我毛骨悚然,你在用尽内存方面效率太低了。
string XmlString = File.ReadAllText
- 这里是第一次将整个文件加载到内存中。
Encoding.UTF8.GetBytes(XmlString)
- 这里你第二次为相同的数据花费内存。
new MemoryStream(...)
- 这里你第三次为相同的数据花费内存。
xmlSerializer.Deserialize
- 此处,内存再次用于反序列化数据。但无法摆脱它。
这样写
using (XmlReader xmlReader = XmlReader.Create(dir + "/" + fileName))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(BXML_LIST));
deserialized = (BXML_LIST)xmlSerializer.Deserialize(xmlReader);
}
在这种情况下,xmlSerializer
将使用 xmlReader
在流中分段从文件中读取数据。
也许,这可能足以解决您的问题。