我需要使用以下结构处理XML文件:
<FolderSizes>
<Version></Version>
<DateTime Un=""></DateTime>
<Summary>
<TotalSize Bytes=""></TotalSize>
<TotalAllocated Bytes=""></TotalAllocated>
<TotalAvgFileSize Bytes=""></TotalAvgFileSize>
<TotalFolders Un=""></TotalFolders>
<TotalFiles Un=""></TotalFiles>
</Summary>
<DiskSpaceInfo>
<Drive Type="" Total="" TotalBytes="" Free="" FreeBytes="" Used=""
UsedBytes=""><![CDATA[ ]]></Drive>
</DiskSpaceInfo>
<Folder ScanState="">
<FullPath Name=""><![CDATA[ ]]></FullPath>
<Attribs Int=""></Attribs>
<Size Bytes=""></Size>
<Allocated Bytes=""></Allocated>
<AvgFileSz Bytes=""></AvgFileSz>
<Folders Un=""></Folders>
<Files Un=""></Files>
<Depth Un=""></Depth>
<Created Un=""></Created>
<Accessed Un=""></Accessed>
<LastMod Un=""></LastMod>
<CreatedCalc Un=""></CreatedCalc>
<AccessedCalc Un=""></AccessedCalc>
<LastModCalc Un=""></LastModCalc>
<Perc><![CDATA[ ]]></Perc>
<Owner><![CDATA[ ]]></Owner>
<!-- Special element; see paragraph below -->
<Folder></Folder>
</Folder>
</FolderSizes>
<Folder>
元素的特殊之处在于它在<FolderSizes>
元素中重复,但也可以在其自身内出现;我估计大约有5个级别。
问题是文件真的很大,高达11GB,所以我很难处理它 - 我有XML文档的经验,但没有任何规模。
我想要做的是将信息导入SQL数据库,因为这样我就能以任何必要的方式处理信息,而不必关心这个巨大的,不切实际的文件。
以下是我尝试过的事情:
<Folder>
元素。这很顺利 - 我认为比其他两种方法更好 - 直到其中一个<Folder>
元素变得相当大,产生An XML operation resulted an XML data type exceeding 2GB in size. Operation aborted.
错误。我读到了它,我不认为这是一个可调节的极限。以下是我认为应该尝试的更多内容:
在我走得更远之前,我想我会先征求一些意见,可能会浪费我的时间。
提前感谢您的时间和帮助。
修改
因此,在我开始处理文件之前,我会检查它并检查大小,以便向用户提供有关处理可能需要多长时间的反馈;我制作了计算的截图:
这大约是每秒1500行;如果我的数学是正确的,如果平均行长度大约为50个字符,即每行50个字节,即每秒75千字节,对于11GB文件应该需要大约40个小时。但这只是踩到每一行。它实际上并不处理该行或对其进行任何操作,因此当开始时,处理速率会显着下降。
这是在大小计算期间运行的方法:
private int _totalLines = 0;
private bool _cancel = false; // set to true when the cancel button is clicked
private void CalculateFileSize()
{
xmlStream = new StreamReader(_filePath);
xmlReader = new XmlTextReader(xmlStream);
while (xmlReader.Read())
{
if (_cancel)
return;
if (xmlReader.LineNumber > _totalLines)
_totalLines = xmlReader.LineNumber;
InterThreadHelper.ChangeText(
lblLinesRemaining,
string.Format("{0} lines", _totalLines));
string elapsed = string.Format(
"{0}:{1}:{2}:{3}",
timer.Elapsed.Days.ToString().PadLeft(2, '0'),
timer.Elapsed.Hours.ToString().PadLeft(2, '0'),
timer.Elapsed.Minutes.ToString().PadLeft(2, '0'),
timer.Elapsed.Seconds.ToString().PadLeft(2, '0'));
InterThreadHelper.ChangeText(lblElapsed, elapsed);
if (_cancel)
return;
}
xmlStream.Dispose();
}
仍在奔跑,27分钟:(
答案 0 :(得分:2)
您可以将XML作为元素的逻辑流读取,而不是尝试逐行读取并将其重新组合在一起。请参阅end of this article
上的代码示例另外,您的问题已经被问到here