Big JSON を読み込む JsonReader の実践

先日書いた「Big JSON を読み込む JsonReader」、
より実践的なサンプルを書いてみる。
JSON素材

{
   "category": "JsonReader テスト",
   "filename": "sample.json",
   "itemlist":[
      {
         "name": "A",
         "flag": true,
         "time": "2020/06/05 22:14:25"
      },
      {
         "name": "B",
         "flag": false,
         "time": "2020/06/05 10:08:17"
      },
      {
         "name": "C",
         "flag": true,
         "time": "2020/06/04 08:54:09"
      }
   ],
   "footer": "ウラン",
   "count": 3
}

この itemlist 配列の1つを表す class

public class Item{
   public String name;
   public boolean flag;
   public LocalDateTime time;

   @Override
   public String toString(){
      return name+" "+" "+flag+" \t"+time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
   }
}

解析実行

try(JsonReader reader = new JsonReader(new InputStreamReader(
   new FileInputStream(jsonFilePath), StandardCharsets.UTF_8))) {
   
   // itemlist 配列の Item を読込む GSON
   Gson gson = new GsonBuilder().serializeNulls()
   .registerTypeAdapter(LocalDateTime.class, LocalDateTimeAdapter.of("yyyy/MM/dd HH:mm:ss"))
   .create();

   // itemlist 配列内で、true
   boolean itemParseRequest = false;

   // itemlist ARRAY 内の OBJECT の PATH
   Pattern targetptn = Pattern.compile("^\\$\\.itemlist\\[\\d+\\]$");

   while((reader.hasNext() || reader.peek().equals(JsonToken.END_ARRAY)
      || reader.peek().equals(JsonToken.END_OBJECT)
      ) && !reader.peek().equals(JsonToken.END_DOCUMENT)
   ){
      JsonToken token = reader.peek();

      StringBuilder sb = new StringBuilder();
      sb.append(token);
      String str;

      if (token.equals(JsonToken.BEGIN_ARRAY)){
         reader.beginArray();
         if (targetptn.matcher(reader.getPath()).matches()){
            itemParseRequest = true;
         }
      }else if(token.equals(JsonToken.END_ARRAY)){
         reader.endArray();
         if (itemParseRequest) itemParseRequest = false;
      }else if(token.equals(JsonToken.BEGIN_OBJECT)){
         if (itemParseRequest) {
            // 配列内、1個の Item 読込み
            Item item = gson.fromJson(reader, new TypeToken<Item>(){}.getType());
            System.out.println("### "+item);
         }else{
            reader.beginObject();
         }
      }else if(token.equals(JsonToken.END_OBJECT)){
         reader.endObject();
      }else if(token.equals(JsonToken.NAME)){
         reader.nextName();
      }else if(token.equals(JsonToken.STRING)){
         str = reader.nextString();

         sb.append(":"+reader.getPath()+" = ");
         sb.append(str);
      }else if(token.equals(JsonToken.NUMBER)){
         long l = reader.nextLong();

         sb.append(":"+reader.getPath()+" = ");
         sb.append(l);
      }else if(token.equals(JsonToken.BOOLEAN)){
         Boolean b = reader.nextBoolean();

         sb.append(":"+reader.getPath()+" = ");
         sb.append(b);
      }else if(token.equals(JsonToken.NULL)){
         reader.nextNull();

         sb.append(":"+reader.getPath()+" = ");
         sb.append("NULL");
      }
      /*** test ***/
      if (!token.equals(JsonToken.BEGIN_OBJECT) && !token.equals(JsonToken.END_OBJECT) && !token.equals(JsonToken.NAME)){
         System.out.println(sb.toString());
      }
      /*************/
   }
}catch(IOException e){
   e.printStackTrace();
}

テスト結果

STRING:$.category = JsonReader テスト
STRING:$.filename = sample.json
BEGIN_ARRAY
### A  true 	2020-06-05 22:14:25
### B  false 	2020-06-05 10:08:17
### C  true 	2020-06-04 08:54:09
END_ARRAY
STRING:$.footer = ウラン
NUMBER:$.count = 3