Java BufferedReader占用的时间太长

Java BufferedReader占用的时间太长,java,json,bufferedreader,Java,Json,Bufferedreader,这是为了更快地读取文件,而不是写入文件。 我有一个150MB的文件,里面有一个JSON对象。我目前使用以下代码来阅读它: String filename ="/tmp/fileToRead"; BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filename), Charset.forName("UTF-8"))); decompressedString = reader.r

这是为了更快地读取文件,而不是写入文件。 我有一个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错误或TLE。文件读取时间超过7秒,导致TLE,因为整个代码的执行时间不能超过7秒。我在decompressedString=reader.readLine;上获得OOM


有什么方法可以减少所使用的内存或完全读取所需的时间吗?

您手头有几个问题:

你抢先解析的内容太多了

自从您说我在decompressedString=reader.readLine;上获得OOM后,当您读取该行时,您得到的错误已经发生

永远不要试图逐行读取数据。BufferedReader.readLine将被阻止,直到您读取了字符\r\n或序列\r\n。当处理任意长度的数据时,您永远无法确定是否会得到其中一个字符。此外,您永远也不确定是否会在数据本身之外获得这些字符。因此,您的字符串可能太长或格式不正确。所以永远不要假装知道格式。解析时必须使用BufferedReader.readLine,而不是在获取数据时

您没有针对您的用例使用适当的库

阅读JSON是很重要的,是的,但是你一次读得太多了。在创建JSON时,您可能希望从InputStream、Reader或任何nio的通道/缓冲区中的一个流构建JSON

目前,您正在从字符串生成JSON。一个巨大的。所以我可以安全地假设,在某一点上,你需要的内存是你需要的两倍。一次在字符串中,一次在最终确定的对象中

为了减少这种情况,请使用适当的库,您可以将上述流之一传递到该库。我在评论中提到以下内容:,和

你的文件可能太大了

如果您获取数据,并且只想在此处获取数据的子集,那么您需要{profileData:{children:}下的所有内容。但你可能有太多了。与profileData处于同一级别的元素有多少?有多少元素与子元素处于同一级别?你知道吗?可能太多了。所有不在profileData.children下的内容都是无用的。这占您总数据的百分比是多少?50%? 90%? 99%

要解决这个问题,您可能需要两件事中的一件:您需要更少的数据,或者您希望能够集中您的请求

如果您想要更少的数据,请让您的数据提供商提供更少的数据:只提供您需要的数据。为什么要得到更多?这毫无意义。告诉他吧,说我要少一点

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


检查这个;这是一个读取文件而不是写入文件的问题。怎么可能是在文件中写入的副本?@Rjiuk关于副本,在BufferReader中读取与写入不同。不要将文件转换为字符串。使用能够直接从文件加载JSONObject的json库。此外,如果您想要读取数据,请不要使用BufferedReader.readLine,除非您100%确定每行足够小,小于4-8 kb。