Big JSON を読み込む JsonReader

大きなJSONGoogle gson で読込むとき、メモリ不足にならないように、fromJson ではなく
JSONトークンで読みだす JsonReader を実行するのだが、注意しなければならない点がある。

以下のように、JsonReader の hasNext() 問い合わせだけでは、END_ARRAY、END_OBJECT を
見つけることができず想定どおりの読出しができない。

try(JsonReader reader = new JsonReader(new InputStreamReader(
      new FileInputStream(jsonFilePath), StandardCharsets.UTF_8))){

   while((reader.hasNext()){|
        //
   }

END_ARRAY、END_OBJECT、END_DOCUMENT をチェックするようにする必要がある。

try(JsonReader reader = new JsonReader(new InputStreamReader(
      new FileInputStream(jsonFilePath), StandardCharsets.UTF_8))){

   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();
      }else if(token.equals(JsonToken.END_ARRAY)){
         reader.endArray();
      }else if(token.equals(JsonToken.BEGIN_OBJECT)){
         reader.beginObject();
      }else if(token.equals(JsonToken.END_OBJECT)){
         reader.endObject();
      }else if(token.equals(JsonToken.NAME)){
         str = 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");
      }
      System.out.println(sb.toString());
   }
}catch(IOException e){
   e.printStackTrace();
}

このコードを見ると長くてそんなに綺麗なコードではない、けれど、
Google gson の JsonReader が優れている点は、階層が深くなっても
再帰メソッドを書く必要がなくて、
この while ループで事足りることだ。