我正在尝试使用Newtonsoft.Json来解析从测试站生成的JSON日志。由于测试过程可能会导致 JSON 内容略有损坏,因此我需要能够解析损坏的数据。更具体地说,当解析器遇到任何损坏或无法识别的字符时,我想尝试跳过当前行并继续解析下一行。
我一直在探索图书馆,但还没有找到解决方案。下面是解析器停止的代码段。 我似乎无法独立于解析器推进流。
StringBuilder jsonBuffer = new StringBuilder();
jsonBuffer = "...";
StringReader sr = new StringReader(jsonBuffer.ToString());
JsonTextReader jr = new JsonTextReader(sr);
jr.SupportMultipleContent = true;
bool go = true;
while (go) {
try {
go = jr.Read();
} catch (Exception e) {
Console.Write("Oops! JSON Read Exception: ");
Console.WriteLine(e.Message);
// can't continue past here...
}
if (!go || jr.TokenType == JsonToken.Undefined) break;
if (jr.Value != null)
Console.WriteLine("Token: {0}, Value: {1}", jr.TokenType, jr.Value);
else
Console.WriteLine("Token: {0}", jr.TokenType);
}
我希望跳过的一些腐败类型示例:
- "
- 键":"双引号值"
- "键":"不完整的值
- 不完整的对象,例如缺少"]"或"}"
我知道最后一项需要更复杂的逻辑来展开任何嵌套对象,但这更像是"可有可无",而 1 和 2 是必备的。
任何帮助都非常感谢!
谢谢John
假设ms
是日志文件的 stram ...
using (StreamReader sr = new StreamReader(ms))
{
do
{
var line = sr.ReadLine();
try
{
JObject obj = JsonConvert.DeserializeObject(line) as JObject;
obj.Dump();
Console.WriteLine("Foo: {0}", obj["foo"]);
}
catch (JsonReaderException jex)
{
Console.WriteLine("MALFORMED: {0}", line);
}
}
while (!sr.EndOfStream);
}
这将:
- 打开文件进行读取
- 单独阅读每一行。
- 尝试将行解析为对象 (JObject)
- 成功时,转储属性值
- 失败时,显示错误消息
- 检查 EOF(文件结尾)
- 如果不是 EOF,请返回到步骤 2。
- 如果为 EOF,请退出。
这将在传递故障时处理最多的行。然后,您可以修改catch{}
块以使用更密集的询问或写出到后日志以进行进一步处理。