BufferedReader耗时太长

时间:2017-04-06 11:10:47

标签: java json bufferedreader

这是为了更快地读取文件而不是写入文件。 我有一个150MB的文件,里面有一个JSON对象。我目前使用以下代码来阅读它:

String filename ="/tmp/fileToRead";
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filename), Charset.forName("UTF-8")));
decompressedString = reader.readLine();
reader.close();
JSONObject obj = new JSONObject(decompressedString);
JSONArray profileData = obj.getJSONObject("profileData").getJSONArray("children");
....

这是一个单行文件,因为它是JSON我不能拆分它(至少我认为是这样)。阅读文件会给我OutOfMemory ErrorTLE。该文件需要超过7秒才能被读取并导致TLE,因为整个代码的执行不能超过7秒。我在decompressedString = reader.readLine();上获得了OOM。

有没有办法可以减少使用的内存或完全读取的时间?

1 个答案:

答案 0 :(得分:2)

您手头有几个问题:

  1. 你是先发制人地解析过。

    当你说“我在decompressedString = reader.readLine();上获得OOM”时,你所读到的错误已经发生了。

    您不应该尝试逐行阅读数据。在您阅读字符BufferedReader.readLine()\r或序列\n之前,\r\n会一直阻止。处理任何长度的数据时,你从不确定你会得到其中一个字符。此外,您永远不会确定您将获得数据本身 之外的那些字符。所以你的字符串可能太长或格式不正确。所以不要假装知道格式。在解析时必须使用BufferedReader.readLine(),而不是在获取数据时使用。{/ p>

  2. 您没有为您的用例使用合适的库

    阅读你的JSON很重要,是的,但你一次读得太多了。在创建JSON时,您可能希望从流(InputStreamReader或任何nio的Channel / Buffer之一)构建它。

    目前,您正在使用String制作JSON。一个巨大的。所以我可以放心地假设你需要两倍于你需要的内存。一次在String中,一次在最终的对象中。

    要减少这种情况,请使用适当的库,您可以将其中一个传递给上面提到的流。我在评论中提到了以下内容:GsonJSON.simpleJackson

  3. 无论如何,您的文件可能太大了。

    如果您获得了数据并且只想获取其中的一部分(此处,您希望{"profileData":{"children": <DATA>}}下的所有内容)。但是你可能太过分了。与profileData在同一级别存在多少个元素?与children在同一级别存在多少个元素?你知道吗?可能太过分了。所有不在profileData.children下的内容都是无用的。您的总数据的百分比是多少? 50%? 90%? 99%?

    要解决此问题,您可能需要以下两种方法之一:您希望获得更少的数据,或者希望能够关注您的请求。

    如果您想要更少的数据,请让您的数据提供商给您更少:只需要您。为什么要获得更多?这没有道理。告诉他,然后说“我想减少”。

    如果您想要有针对性的数据,请使用允许您解析和减少数据量的库。您可能希望拥有一个允许您这样说的库:“解析此JSON并仅返回processingData.children元素”。 不幸的是我知道没有图书馆可以做到这一点。如果其他人这样做,请添加评论或回答。显然,如果您自己使用JsonReader并有选择地使用skipValue(),Gson可以这样做。