0

我正在尝试使用 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);
}

我希望跳过的腐败类型的一些示例:

  • "key": ""双引号值""
  • "key": "不完整的值
  • 不完整的对象,例如缺少 ']' 或 '}'

我知道最后一项需要一些更复杂的逻辑来展开任何嵌套对象,但这更像是一个“不错的”,而 1 和 2 是必须的。

任何帮助深表感谢!

谢谢,约翰

4

1 回答 1

0

假设ms您的日志文件是一个流...

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);
}

这将:

  1. 打开文件进行阅读
  2. 单独阅读每一行。
  3. 尝试将行解析为对象 (JObject)
    • 成功后,转储属性值
    • 失败时,显示错误信息
  4. 检查 EOF(文件结尾)
    • 如果不是 EOF,则返回步骤 2。
    • 如果EOF,退出。

这将在传递失败的同时处理最多的行。然后,您可以修改catch{}块以使用更强烈的询问或写出日志以进行进一步处理。

于 2015-02-03T02:35:30.720 回答