这是为了更快地读取文件而不是写入文件。 我有一个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 Error
或TLE
。该文件需要超过7秒才能被读取并导致TLE,因为整个代码的执行不能超过7秒。我在decompressedString = reader.readLine();
上获得了OOM。
有没有办法可以减少使用的内存或完全读取的时间?
答案 0 :(得分:2)
您手头有几个问题:
你是先发制人地解析过。
当你说“我在decompressedString = reader.readLine();
上获得OOM”时,你所读到的错误已经发生了。
您不应该尝试逐行阅读数据。在您阅读字符BufferedReader.readLine()
或\r
或序列\n
之前,\r\n
会一直阻止。处理任何长度的数据时,你从不确定你会得到其中一个字符。此外,您永远不会确定您将获得数据本身 之外的那些字符。所以你的字符串可能太长或格式不正确。所以不要假装知道格式。在解析时必须使用BufferedReader.readLine()
,而不是在获取数据时使用。{/ p>
您没有为您的用例使用合适的库
阅读你的JSON很重要,是的,但你一次读得太多了。在创建JSON时,您可能希望从流(InputStream
,Reader
或任何nio的Channel
/ Buffer
之一)构建它。
目前,您正在使用String
制作JSON。一个巨大的。所以我可以放心地假设你需要两倍于你需要的内存。一次在String中,一次在最终的对象中。
要减少这种情况,请使用适当的库,您可以将其中一个传递给上面提到的流。我在评论中提到了以下内容:Gson,JSON.simple和Jackson。
无论如何,您的文件可能太大了。
如果您获得了数据并且只想获取其中的一部分(此处,您希望{"profileData":{"children": <DATA>}}
下的所有内容)。但是你可能太过分了。与profileData
在同一级别存在多少个元素?与children
在同一级别存在多少个元素?你知道吗?可能太过分了。所有不在profileData.children
下的内容都是无用的。您的总数据的百分比是多少? 50%? 90%? 99%?
要解决此问题,您可能需要以下两种方法之一:您希望获得更少的数据,或者希望能够关注您的请求。
如果您想要更少的数据,请让您的数据提供商给您更少:只需要您。为什么要获得更多?这没有道理。告诉他,然后说“我想减少”。
如果您想要有针对性的数据,请使用允许您解析和减少数据量的库。您可能希望拥有一个允许您这样说的库:“解析此JSON并仅返回processingData.children
元素”。 不幸的是我知道没有图书馆可以做到这一点。如果其他人这样做,请添加评论或回答。显然,如果您自己使用JsonReader
并有选择地使用skipValue()
,Gson可以这样做。