2012-06-30 3 views
4

Я хочу отправить команду на сервер и узнать, получаю ли я ответ.Как я могу читать из BufferedReader в Java без блокировки?

Прямо сейчас я использую readline() функция, которая блокируется до тех пор, пока не будет ответа от сервера, но все, что я хочу сделать, это проверить, что на сервере есть ответ.

Я попытался использовать ready() или reset(), чтобы избежать этого блока, но это не поможет.

Это заставляет мою программу застревать в ожидании ответа сервера, чего никогда не происходит. InputStreamReader, похоже, делает то же самое, по моему пониманию вещей.

Другие вопросы, которые я нашел здесь по этому вопросу, не ответил на мой вопрос, , поэтому, пожалуйста, если вы ответите на мой вопрос, это будет здорово.

+0

Интересно было бы, если сервер выполнил 'flush()' и обеспечил отправку новой строки ('println'). –

+0

В чем разница между блокировкой до тех пор, пока не появится ответ, и выясните, есть ли ответ? Вы должны ждать на сервере в любом случае. – EJP

ответ

1

Может быть все, что вам нужно, это InputStream без упаковки его в BufferedReader

while (inputStream.available() > 0) { 
    int i = inputStream.read(tmp, 0, 1024); 
    if (i < 0) 
      break; 
    strBuff.append(new String(tmp, 0, i)); 
} 

Я надеюсь, что это помогает.

+0

Для этой техники не требуется переход к InputStream. – EJP

+0

Это не делает ничего, чтобы удалить поведение блокировки –

+0

@EJP Не даст ли он возможность прекратить ждать, если нет ввода? В своем вопросе он сказал: «Но все, что я хочу сделать, это проверить, что на сервере есть ответ». –

3

Если вы хотите читать ответы асинхронно, я предлагаю начать поток, который читает BufferedReader. Это намного проще в коде и легче контролировать.

+1

Я думал, что BufferedReader - лучшая практика для чтения данных без блокировки. Но для некоторых устройств «readLine» и даже «готовый» блок блокировки («ready» никогда не блокируется): http://stackoverflow.com/questions/27427213/bufferedreader-ready-blocking –

0

Я сделал что-то подобное недавно с помощью CountDownLatch. Там могут быть несколько лучших способов, но это довольно легко и, кажется, работает достаточно хорошо. Вы можете настроить дату ожидания CountDownLatch в соответствии с вашими потребностями.

package com.whatever; 

import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.net.URL; 
import java.net.URLConnection; 
import java.util.concurrent.CountDownLatch; 
import java.util.concurrent.TimeUnit; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

public class TestRead { 
    private static final Logger log = LoggerFactory.getLogger(TestRead.class); 
    private CountDownLatch latch = new CountDownLatch(1); 

    public void read() { 
     URLReader urlReader = new URLReader(); 
     Thread listener = new Thread(urlReader); 
     listener.setDaemon(true); 
     listener.start(); 
     boolean success = false; 
     try { 
      success = latch.await(20000, TimeUnit.MILLISECONDS); 
     } catch (InterruptedException e) { 
      log.error("error", e); 
     } 
     log.info("success: {}", success); 
    } 

    class URLReader implements Runnable { 
     public void run() { 
      log.info("run..."); 
      try { 
       URL oracle = new URL("http://www.oracle.com/"); 
       URLConnection yc = oracle.openConnection(); 
       BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream())); 
       String inputLine; 
       while ((inputLine = in.readLine()) != null) 
        System.out.println(inputLine); 
       in.close(); 
       latch.countDown(); 
      } catch (Exception ex) { 
       log.error("error", ex); 
      } 
      log.info("consumer is done"); 
     } 

    } 
    public static void main(String[] args) { 
     TestRead testRead = new TestRead(); 
     testRead.read(); 
    } 
} 
Смежные вопросы