Как я могу установить тайм-аут для BufferedReader на основе URLConnection в Java?

Я хочу прочитать содержимое URL-адреса, но не хочу «зависать», если URL-адрес не отвечает. Я создал BufferedReader, используя URL-адрес ...

URL theURL = new URL(url);
URLConnection urlConn = theURL.openConnection();
urlConn.setDoOutput(true);
BufferedReader urlReader = new BufferedReader(newInputStreamReader(urlConn.getInputStream()));

... а затем начал цикл для чтения содержимого ...

do
    {
    buf = urlReader.readLine();
    if (buf != null)
        {
        resultBuffer.append(buf);
        resultBuffer.append("\n");
        }
    }
while (buf != null);

... но если чтение зависает, значит зависает приложение.

Есть ли способ, не доводя код до уровня сокета, при необходимости "тайм-аут" чтения?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
10
0
14 257
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Я думаю, что URLConnection.setReadTimeout - это то, что вы ищете.

Начиная с Java 1.5, можно установить тайм-аут чтения в миллисекундах для базового сокета с помощью метода setReadTimeout (int timeout) в классе URLConnection.

Обратите внимание, что есть также setConnectTimeout (int timeout), который будет делать то же самое для начального подключения к удаленному серверу, поэтому важно установить и его.

Не openConnection () запускает соединение, поэтому установка тайм-аута открытого соединения будет иметь эффект, или он считывает значение даже после того, как запустил процесс соединения?

William 16.11.2009 23:29

Если у вас java 1.4:

Я предполагаю, что тайм-аут соединения (URLConnection.setConnectTimeout(int timeout)) бесполезен, потому что вы выполняете какую-то потоковую передачу.

--- Не убивайте нить --- Это может вызвать неизвестные проблемы, открытые дескрипторы и т. д.

Создайте java.util.TimerTask, где вы проверите, завершили ли вы процесс, в противном случае закройте BufferedReader и OutputStream URLConnection

Вставьте логический флаг isFinished и установите для него значение true в конце цикла и значение false перед циклом.

TimerTask ft = new TimerTask(){
   public void run(){
     if (!isFinished){
       urlConn.getInputStream().close();
      urlConn.getOutputStream().close();
     }
   }
};

(new Timer()).schedule(ft, timeout);

Это, вероятно, вызовет исключение ioexception, поэтому вам нужно его поймать. Исключение само по себе неплохо. Я опускаю некоторые объявления (например, финалы), чтобы анонимный класс мог получить доступ к вашим переменным. Если нет, то создайте POJO, который поддерживает ссылку, и передайте ее в timertask.

Это хорошее решение, но я думаю, что ваша задача сработает только один раз. Это, вероятно, не удастся для долгосрочного процесса передачи, поэтому было бы лучше запустить с интервалом и остановить таймер, когда это будет сделано. Хотя идея интересная.

jsight 18.09.2008 19:32

Я недавно работал над этой проблемой в среде JVM 1.4. Стандартный ответ - использовать системные свойства sun.net.client.defaultReadTimeout (время ожидания чтения) и / или sun.net.client.defaultConnectTimeout. Они задокументированы в Сетевые свойства и могут быть установлены с помощью аргумента -D в командной строке Java или с помощью вызова метода System.setProperty.

Предположительно, они кэшируются реализацией, поэтому вы не можете изменить их с одного на другое, поэтому, если они используются один раз, значения сохраняются.

Также они действительно не работают для SSL-соединений, таких как HttpsURLConnection. Есть и другие способы справиться с этим, используя собственный SSLSocketFactory.

Опять же, все это относится к JVM 1.4.x. В версии 1.5 и выше у вас есть больше методов, доступных вам в API (как отметили другие респонденты выше).

Для Java 1.4 вы можете использовать SimpleHttpConnectionManager.getConnectionWithTimeout (hostConf, CONNECTION_TIMEOUT) из Apache

Другие вопросы по теме