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

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

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

[    {    "Rep":
        {
        "date":"2013-07-26 00:00:00",
        "TBook":
        [
            {
            "TBookC":"ABCD",            
            "Records":
            [
                {"TSSName":"AAA", 
                    ... 
                },
                {"TSSName":"AAB", 
                    ... 
                },
                {"TSSName":"ZZZ", 
                ... 
                }
            ] } ] } } ]

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

configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false);
MappingJsonFactory factory = new MappingJsonFactory();
mapper = new ObjectMapper(factory); 
mapper.configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES,false);
mapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS,false);
parser = factory.createJsonParser(iStream);
mapper.readValue(parser, JsonNode.class);

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

... 
                },
                {"TSSName":"ZZZ", 
                ... 
                },
                {"TSSName":"ZZZ2", 
                ... 
                }
            ] } ] } } ]

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

{"TSSName":"ZZZ", 
                ... 
                },
                {"TSSName":"ZZZ2", 
                ... 
                },
                ...
            ] } ] } } ]

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

7fhtutme

7fhtutme1#

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

相关问题