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

StackOverflow https://stackoverflow.com/questions/93357

  •  01-07-2019
  •  | 
  •  

Вопрос

Я хочу прочитать содержимое 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);

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

Есть ли способ, не измельчая код до уровня сокета, «приостановить» чтение, если это необходимо?

Это было полезно?

Решение

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

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

Если у вас 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);

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

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

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

Совсем недавно я работал над этой проблемой в среде 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top