在不增加堆大小的情况下解析巨大的json文件

在不增加堆大小的情况下解析巨大的json文件,json,jvm,heap,jackson,Json,Jvm,Heap,Jackson,我在解析一个巨大的json文件(200mb)时遇到问题。起初,我尝试使用JACKSON将json解析为一棵树。但是,我遇到了堆大小问题。出于某种原因,增加堆大小不是一个选项 JSON格式: { "a1":{ "b1":{"c1":"somevalue", "c2":"somevalue"}, ... }, "a2":{ "b1":{"c1":"somevalue"},"c3":"somevalue"}, ... }, .... } 我想做的是产生像 str1 = "{

我在解析一个巨大的json文件(200mb)时遇到问题。起初,我尝试使用JACKSON将json解析为一棵树。但是,我遇到了堆大小问题。出于某种原因,增加堆大小不是一个选项

JSON格式:

{ 
    "a1":{ "b1":{"c1":"somevalue", "c2":"somevalue"}, ... },
    "a2":{ "b1":{"c1":"somevalue"},"c3":"somevalue"}, ... },
    ....
}
我想做的是产生像

str1 = "{ "b1":{"c1":"somevalue", "c2":"somevalue"}, ... }"
str2 = "{ "b1":{"c3":"somevalue"},"c4":"somevalue"}, ... }"
有没有办法做到这一点而不出现堆问题

在python中,有一种简单的方法可以做到这一点,并且没有堆问题(没有JVM)

一些想法: 我可能不需要使用Jackson树方法,因为我只需要字符串。 流式Jackson可能是一种选择,但我很难编写它,因为我们的json格式非常灵活。任何建议都将不胜感激


多亏了使用基于对象的数据绑定更节省内存,所以如果您可以定义Java类来匹配结构,这是一种更好的方法:更快,使用更少的内存。 但有时在结构未知的情况下需要树模型

流式API可以提供帮助,您还可以混合使用各种方法:迭代JSON令牌,然后使用
JsonParser.readValueAs(MyType.class)
JsonParser.readValueAsTree()

这只允许您为JSON输入的子集在内存中构建树或对象。

最后,我使用了流方法。我从http打开一个流,每次读取固定数量的字节到缓冲区。在我确定我已经在缓冲区中构建了一个有效的字符串之后,我发出该字符串并截断缓冲区。这样,我使用的内存很少。谢谢

所以,您正在寻找一个JSON流式API,找到了一个,但使用起来有困难。如果没有看到您尝试过的代码和您遇到的困难的清晰描述,我们如何帮助您呢?如果您的结果是字符串,为什么不立即解析字符串呢。
regex
能满足您的需求吗?@lichengwu谢谢!你的建议真的很有用。是的,事实上我发现我不需要解析json。我应该使用一些纯字符串流方法谢谢!你的建议很有帮助。以下是我的一些想法:我们的数据格式非常灵活,无结构,因此我无法为它定义模式或类。通过使用流方法,我们可以从inputstream获得jsonparser,而readValueAsTree与tree方法相同,它将为json字符串构建一个完整的树。整个树将消耗比原始jsonNo、
JsonParser多几倍的内存。readValueAsTree()
不一定会读取整个流,但只有一个以令牌解析器指向的值(或者,如果没有,则指向下一个令牌)。如果流由对象序列或数组组成,则可以逐个读取它们。因此,您需要做的就是将
JsonParser
升级到第一个值标记(START_对象或START_数组),然后读取为tree。还有一种可能性:您还可以绑定到
java.util.Map
java.util.List
,这将给出“非类型化”对象(映射或值列表,与tree方法非常类似)。这将不需要自定义类。这样,我为每个小json字符串构建一个树模型,它使用的内存比为整个json构建一个完整的树要少
data  = json.loads(xxx)
for key,val in data.iteritems():
    puts val