2014-12-04 74 views
0

我正在使用傑克遜來處理JSON在Hadoop中的塊。這意味着,它們是大塊文件(在我的問題中它是128M但它並不重要)。 出於效率的原因,我需要它流式傳輸(不可能在內存中構建整個樹)。傑克遜jsonparser重新啓動解析破碎的JSON

我正在使用JsonParser和ObjectMapper的混合來讀取我的輸入。 目前,我正在使用不可拆分的自定義InputFormat,因此我可以閱讀我的整個JSON。

的(有效)JSON的結構是這樣的:

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

我想在我的RecordReader閱讀的記錄是「記錄」元素中的元素。 「...」意味着那裏有更多的信息,這符合我的記錄。 如果我只有一個拆分,那完全沒有問題。 我使用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); 

現在,讓我們想象我有兩個inputsplits文件(即有很多的元素在「史記」)。 有效的JSON從第一次分割開始,並且我讀取並保存了標題(每個記錄都需要這些標題,在本例中爲「日期」字段)。

分割會切割記錄數組中的任何位置。因此,讓我們假設我有第二次分裂是這樣的:

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

我可以檢查之前,我開始分析,以InputStream的(FSDataInputStream)移動到下一個「TSSNAME」記錄的開始(「{」)在其中(並且這樣做確定)。在開始時丟棄尾隨的「垃圾」是很好的。因此,我們得到這樣的:

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

然後我把它處理到JsonParser/ObjectMapper對上面看到的。 第一個對象「ZZZ」被讀取OK。 但是對於下一個「ZZZ2」,它打破了:JSONParser關於格式錯誤的JSON的投訴。它遇到一個「,」不在數組中。所以它失敗了。然後我不能繼續閱讀我的記錄。

這個問題怎麼解決,所以我仍然可以從第二個(和第n個)分裂讀我的記錄?我怎樣才能讓解析器忽略逗號上的這些錯誤,或者讓解析器事先知道它正在讀取數組的內容?

回答

0

看起來好像只是捕捉異常:解析器繼續運行,並且能夠通過ObjectMapper繼續讀取對象。

我不太喜歡它 - 我想要一個解析器無法在非標準或甚至不良JSON上拋出異常的選項。所以我不知道這是否完全回答了這個問題,但我希望它有幫助。