2017-06-22 12 views
0

私はいくつかのjsonデータで15-16分ごとに更新されるテキストファイルを持っています。これらのjsonデータは、####行で区切られています。ファイルのスニペットは:Javaで区切られたjsonオブジェクトでテキストファイルを解析するには?

[{"accountId":"abc","items":[{"serviceName":"XYZ","dataCenter":"TG","startTimeUtc":"2017-04-05T19:57:33.509+0000","endTimeUtc":"2017-04-05T19:57:33.509+0000","usage":[{"resourceName":"XYZ_EE_PAAS_GATEWAYS","quantity":7,"units":"number"}]}]},{"accountId":"XYZp1cm9mbe","items":[{"serviceName":"XYZ","dataCenter":"TG","startTimeUtc":"2017-04-05T19:57:33.509+0000","endTimeUtc":"2017-04-05T19:57:33.509+0000","usage":[{"resourceName":"XYZ_EE_PAAS_GATEWAYS","quantity":6,"units":"number"}]}]}] 
###################### 
[{"accountId":"abc","items":[{"serviceName":"XYZ","dataCenter":"TG","startTimeUtc":"2017-04-05T19:59:33.523+0000","endTimeUtc":"2017-04-05T19:59:33.523+0000","usage":[{"resourceName":"XYZ_EE_PAAS_GATEWAYS","quantity":7,"units":"number"}]}]},{"accountId":"XYZp1cm9mbe","items":[{"serviceName":"XYZ","dataCenter":"TG","startTimeUtc":"2017-04-05T19:59:33.523+0000","endTimeUtc":"2017-04-05T19:59:33.523+0000","usage":[{"resourceName":"XYZ_EE_PAAS_GATEWAYS","quantity":6,"units":"number"}]}]}] 
###################### 
[{"accountId":"abc","items":[{"serviceName":"XYZ","dataCenter":"TG","startTimeUtc":"2017-04-05T20:01:33.531+0000","endTimeUtc":"2017-04-05T20:01:33.531+0000","usage":[{"resourceName":"XYZ_EE_PAAS_GATEWAYS","quantity":7,"units":"number"}]}]},{"accountId":"XYZp1cm9mbe","items":[{"serviceName":"XYZ","dataCenter":"TG","startTimeUtc":"2017-04-05T20:01:33.531+0000","endTimeUtc":"2017-04-05T20:01:33.531+0000","usage":[{"resourceName":"XYZ_EE_PAAS_GATEWAYS","quantity":6,"units":"number"}]}]}] 
###################### 

このファイルは15-16分ごとに新しいエントリで更新されます。私はファイルを読んで、####行を除く最新のエントリをjsonオブジェクトに格納したいと思います。どのようにJavaでそれを行うには?私は一定ではないので、15分間隔を使用したくない。

私の単純な要件は、私がファイルを読んで、###行の上の最後のjsonを取得したいと思っていた時点です。 Javaの8で

+1

2つの質問:1番目:各アップデートに1行だけ追加されますか?第2:あなたのファイルはどれくらい大きくなりますか?これらの質問に対する答えは、あなたが選ぶべきソリューションに大きな影響を与えます:ファイルが比較的小さい場合、各アップデートで完全なファイルを再解析するための大きなオーバーヘッドはありません。各更新で1行だけが追加された場合は、更新をトリガーとして使用して最後の行のみを解析することができます。 – mschenk74

+0

@ mschenk74 1番目:各アップデートに1行だけ追加されますか? これは、単一行のエントリとして提供されるか、または複数行の書式付きjsonエントリとして提供される場合があります。 2番目:ファイルのサイズはどのくらい大きくなりますか? ファイルの最大エントリ数は15です。 – saurav

+2

あなたのこの追加情報があれば、あなたのケースでは最適化の必要はないと言います。だから私は以下のSebastion Kruseの答えから始めます。ソリューションの速度が遅すぎない限り、ソリューションを最適化しないでください。注意:各アップデートで完全なファイルを解析するときは、以前のアップデートですでに解析した行を検出するロジックをコーディングする必要があります。 – mschenk74

答えて

1

、あなたはこのようにそれを行うことができます。

public JsonObject retrieveLastEntry(Path path) throws IOException { 
    String[] jsonLines = Files.lines(path) 
    .filter(line -> !line.equals("######################") 
    .toArray(); 
    String lastJsonLine = jsonLines[jsonLines.length - 1]; 
    return MyFavoriteJsonParser.parse(lastJsonLine); 
} 

MyFavoriteJsonParser(多分this questionを見て)あなたが使用したいものは何でもJSONライブラリを指します。ここではパフォーマンスに関する考慮事項はほとんどありません。ファイルが非常に大きい(数MBよりもかなり大きい)場合は、.toArray()の呼び出しが適切でない可能性があります。実際、パフォーマンスが非常に重要な場合は、ファイルを逆方向​​に解析することも検討する必要があります。しかし、パフォーマンスの最適化のためのゴールデンルールは、まず簡単な解決策をとって、十分なパフォーマンスが得られないかどうかを(そしてどこで)確認するかです。

しかし、JSONがラインをまたいだ場合、Stream APIは最適な選択肢ではありません。その場合には、定期的な反復が救助に来る:

public JsonObject retrieveLastEntry(File file) throws IOException { 
    String lastJson = ""; 
    StringBuffer sb = new StringBuffer(); 
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileReader(file), "UTF-8")))) { 
    String line; 
    while ((line = reader.readLine()) != null) { 
     if (line.equals("######################") { 
     lastJson = sb.toString(); sb.setLength(0); 
     } else { 
     sb.append(line).append('\n'); 
     } 
    } 
    return MyFavoriteJsonParser.parse(lastJsonLine); 
} 

基本的な考え方は、###...間に線を集約し、新たな区切りに到達するたびに変数にそれらを置くことです。あなたはまだ入力が全くないという事例を考えて、IOExceptionを適切に処理したいかもしれません。

これはかなり慣れ親しんだ方法だと思います。

+0

お返事ありがとうございます。非常に役に立ちました。私の唯一の関心事は、json全体が1行ではなく、複数行でjsonをフォーマットした場合の対処方法です。 #############は唯一のセパレータであり、エントリの終わりを示します。 – saurav

+0

それは良い点です。あなたの例はそれをあきらめていませんでしたが、私はそれを更新します。連続したセパレータは、常にセパレータがあるのでしょうか? –

+0

はい、私も質問を更新しました。セパレータは、各エントリの後にそこにあります。私。eが、それは次のようになりますので、ファイルが空になっていると言うと、1つのエントリが追加できます: これは最初のエントリ ある###################### ###第2のエントリの後 : これは、これはTHES econdエントリ ある最初のエントリ #########################あります私はそれを適切にフォーマットすることはできませんよコメントで######################### 。 – saurav

関連する問題