我试图确定解析.svclog文件的最有效方法是什么。为了给你更多的上下文,我处理的.svclog文件看起来像http://msdn.microsoft.com/en-us/library/aa751795.aspx中的内容。跟踪逻辑在.svclog文件中创建<E2ETraceEvent/>
个元素,将它们全部放在一行上,因此最终得到10兆字节的单行XML,例如:
<E2ETraceEvent [...]</E2ETraceEvent><E2ETraceEvent [...] </E2ETraceEvent>...
从这条巨线一次读取一个<E2ETraceEvent/>
元素的最有效方法是什么?我知道有一些工具可以基本上为你缩进XML,并将更改保存到同一个文件或一个单独的文件中。这是我宁愿跳过的另一个步骤,因为考虑到我可能必须处理的这些文件的数量,性能将非常重要。我甚至不想在开始处理之前缩进一百个胖文件。
我可以将整个文件加载到内存中并将其视为一个字符串(在我的情况下,它们的上限为30兆),但我想要实现某种&#34;对数合并&#34; #34;未来的逻辑,我可能需要将数百个文件拼接在一起,因此一次将它们全部加载到内存中就不会发生。
我可能会使用带有"<E2ETraceEvent.*?</E2ETraceEvent>"
的正则表达式并一次前进一个元素(这有效吗?)。
我实际上可以手动实现一次读取一个字符的状态机。这听起来很糟糕:))
很多选择,但我正在寻找真正干净和优雅的东西。
PS。在解析中处理单行文件真的很常见吗?我之前没有完成太多的解析工作,但几乎所有与我合作过的工具似乎都依赖于一次读取 x 的行数。当你在整个文件中没有一个换行符时,所有这一切都变得毫无用处。
答案 0 :(得分:2)
由于你的基本文件片段而不是普通文件,你可以use the underlying XmlReader classes to process it:
// just a test string... XmlTextReader can take a Stream as first argument instead
var elements = @"<E2ETraceEvent/><E2ETraceEvent/>";
using (var reader = new XmlTextReader(elements, XmlNodeType.Element, null))
{
while (reader.Read())
{
Console.WriteLine(reader.Name);
}
}
这将一次读取一个元素的XML文件,并且不会将整个文档保留在内存中。无论你在读取循环中做什么都是特定于你的用例:)
答案 1 :(得分:2)
如果有人遇到破损痕迹的问题,我就制作了这个PowerShell脚本。
function process-event
{
$dest = $args[1]
Get-ChildItem $args[0] |
Select-String "([<]E2ETraceEvent.*?(?=[<]E2ETraceEvent))" -AllMatches |
ForEach-Object { $matches = $_.Matches;
foreach ($m in $matches) {
Add-Content -Path $dest -Value $m.Value } };
}
function process-log
{
'<?xml version="1.0" encoding="utf-8"?><Tracing>' | Out-File $args[1]
process-event $args[0] $args[1]
'</Tracing>' | Out-File $args[1] -append
}
process-log .\the_log.svclog .\the_log_fix.svclog
已更新! 这不是很快,我只需要300mb文件,但它会修复它们而不是烧掉所有RAM。