如何在Java中用分离的json对象解析文本文件?

时间:2017-06-22 06:30:27

标签: java json parsing

我有一个文本文件,每15-16分钟就会有一些json数据更新。这些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。

1 个答案:

答案 0 :(得分:1)

使用Java 8,你可以这样做:

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指的是您想要使用的任何JSON库(可能需要查看this question)。这里可能没有什么性能考虑因素。如果您的文件非常大(远远超过几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的情况。

我认为这几乎是惯用的做法。