jackson jsonparser在中断的json中重新启动解析

q7solyqu  于 2021-05-30  发布在  Hadoop
关注(0)|答案(1)|浏览(533)

我使用jackson来处理hadoop中成片出现的json。这意味着,它们是大文件,被切成块(在我的问题中,它是128m,但其实并不重要)。出于效率考虑,我需要它是流式的(不可能在内存中构建整个树)。
我混合使用jsonparser和objectmapper来读取输入。目前,我使用的是一种不可拆分的自定义inputformat,因此我可以读取整个json。
(有效)json的结构类似于:

  1. [ { "Rep":
  2. {
  3. "date":"2013-07-26 00:00:00",
  4. "TBook":
  5. [
  6. {
  7. "TBookC":"ABCD",
  8. "Records":
  9. [
  10. {"TSSName":"AAA",
  11. ...
  12. },
  13. {"TSSName":"AAB",
  14. ...
  15. },
  16. {"TSSName":"ZZZ",
  17. ...
  18. }
  19. ] } ] } } ]

我想在recordreader中读取的记录是“records”元素中的元素。“…”意味着那里有更多的信息,这符合我的记录。如果我有一个唯一的分裂,没有任何问题。我使用jsonparser进行细粒度处理(头并移到“records”标记),然后使用objectmapper和jsonparser将记录作为对象读取。详情:

  1. configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false);
  2. MappingJsonFactory factory = new MappingJsonFactory();
  3. mapper = new ObjectMapper(factory);
  4. mapper.configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES,false);
  5. mapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS,false);
  6. parser = factory.createJsonParser(iStream);
  7. mapper.readValue(parser, JsonNode.class);

现在,假设我有一个包含两个inputspilt的文件(即“records”中有很多元素)。有效的json从第一个split开始,我读取并保留标题(每个记录都需要这些标题,在本例中是“date”字段)。
拆分将剪切记录数组中的任何位置。假设我得到第二次分裂,像这样:

  1. ...
  2. },
  3. {"TSSName":"ZZZ",
  4. ...
  5. },
  6. {"TSSName":"ZZZ2",
  7. ...
  8. }
  9. ] } ] } } ]

在开始解析之前,我可以检查是否将inputstream(fsdatainputstream)移动到记录的开头(“{”),其中包含下一个“tssname”(这样做是正确的)。在开始时丢弃后面的“垃圾”是可以的。所以我们得到了这个:

  1. {"TSSName":"ZZZ",
  2. ...
  3. },
  4. {"TSSName":"ZZZ2",
  5. ...
  6. },
  7. ...
  8. ] } ] } } ]

然后我将其处理到上面看到的jsonparser/objectmapper对。第一个对象“zzz”读取正常。但是对于下一个“zzz2”,它打破了:jsonparser抱怨json格式错误。它遇到了一个“,”不在数组中。所以它失败了。然后我就不能继续看我的记录了。
如何解决这个问题,使我仍然可以阅读我的记录,从第二次(和第n次)分裂?如何让解析器忽略逗号上的这些错误,或者让解析器提前知道它正在读取数组的内容?

7fhtutme

7fhtutme1#

似乎只要捕捉到异常就可以了:解析器继续运行,并且能够通过objectmapper继续读取对象。
我真的不喜欢它-我想要一个解析器不能在非标准甚至坏的json上抛出异常的选项。所以我不知道这是否完全回答了这个问题,但我希望它能有所帮助。

相关问题