Закрытие BufferedReader и InputStreamReader

Этот фрагмент кода создает проблемы с утечкой памяти из-за BufferedReader и InputStreamReader что, я думаю, может происходить из-за некоторых исключений. Как мне его изменить?

try{
    URL url = new URL(sMyUrl);
    BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
    while ((str = in.readLine()) != null) {
        jsonString += str;
    }
    in.close();
}catch(Exception e){

}

person Pit Digger    schedule 30.08.2012    source источник
comment
Может быть логика move close() для окончательной блокировки? Вы уверены, что при чтении (или) закрытии соединения не происходит исключений?   -  person kosa    schedule 30.08.2012
comment
Пробовали написать e.printStackTrace() в своем предложении catch, чтобы увидеть, были ли выброшены исключения?   -  person Aske B.    schedule 30.08.2012


Ответы (2)


Было бы безопаснее закрыть поток с помощью блока try..finally. Вы также можете использовать StringBuilder, так как он предназначен для объединения строк. Вы также должны избегать захвата Exception и ничего с ним не делать. Кроме того, ваш код объединяет строки без разрывов строк. Это вполне может быть не то, что вы хотите, и в этом случае append("\n"), когда вы читаете каждую строку.

Вот версия с этими изменениями:

StringBuilder json = new StringBuilder();
try {
    URL url = new URL(sMyUrl);
    BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
    try {
        String str;
        while ((str = in.readLine()) != null) {
            json.append(str).append("\n");
        }
    } finally {
        in.close();
    }
} catch (Exception e) {
    throw new RuntimeException("Failed to read JSON from stream", e);
}
person ᴇʟᴇvᴀтᴇ    schedule 30.08.2012
comment
Нужно ли закрывать InputStreamReader? Или он закрыт, так как читатель буфера создаст новый объект? - person Pit Digger; 30.08.2012
comment
Нет необходимости явно закрывать InputStreamReader, так как он будет закрыт автоматически, когда вы закроете BufferedReader. - person ᴇʟᴇvᴀтᴇ; 30.08.2012
comment
@aetheria, спасибо. В любом случае мне нужен хороший учебник по потокам Java. - person Maksim Dmitriev; 18.02.2013
comment
@aetheria Я видел в некоторых учебниках, что ресурс проверяется на нулевое значение перед закрытием. Но когда я попробовал это, он попросил меня заключить их в другой блок try catch. это почему? и важно ли проверять нулевое значение перед закрытием ресурса - person Kasun Siyambalapitiya; 17.01.2017
comment
Касун, предлагаю вам разместить отдельный вопрос с примером. - person ᴇʟᴇvᴀтᴇ; 17.01.2017
comment
Этот ответ неверен, так как он даже не компилируется (по крайней мере, в java7). Переменная BufferedReader in объявлена ​​в области действия блока try и не отображается в области действия блока finally. Переменная может даже не быть назначена, если MalformedURLException выбрасывается из конструктора класса URL. - person Krzysztof Jabłoński; 03.04.2018
comment
Нет, это неправильное прочтение. Есть два блока try. Переменная in не определена внутри закрывающего ее блока try. - person ᴇʟᴇvᴀтᴇ; 05.04.2018
comment
@ᴇʟᴇvᴀтᴇ Ты прав. Что-то должно быть не так со мной тогда. Извините за недопонимание. - person Krzysztof Jabłoński; 07.05.2018

Код не красивый, но не будет создавать утечки памяти. Я предлагаю вам использовать профилировщик памяти, чтобы определить, где используется ваша память. В противном случае вы просто догадываетесь, даже если у вас есть десятилетний опыт настройки производительности в Java;)

Лучшей альтернативой является использование Java 7.

URL url = new URL(sMyUrl);
try(BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()))) {
  while ((str = in.readLine()) != null) {
     jsonString.append(str).append("\n");
  }
}

Если у вас есть Java 6 или старше, вы можете использовать.

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()))) {
try {
  while ((str = in.readLine()) != null) {
     jsonString.append(str).append("\n");
  }
} finally {
  in.close();
}
person Peter Lawrey    schedule 30.08.2012
comment
Спасибо ! Нужно ли закрывать InputStreamReader? - person Pit Digger; 30.08.2012
comment
@SoneshDabhi Когда вы закрываете BufferedReader, он закрывает InputStreamreader, который закрывает InputStream, полученный вами из openStream() и т. д. - person Peter Lawrey; 30.08.2012