2016-09-14 136 views
-2

在与HttpsURLConnection建立连接后,我读取输入缓冲区。一切工作正常,但如果返回的数据是空的(只有200 0字节) reader.readLine()引发IOException。 (编辑:它实际上是一个超时)BufferedReader.readLine():如何避免空数据时的异常?

什么IF语句我可以在reader.readLine()之前写,所以我可以提前抓住这个?

注意:一个棘手的部分可能是我们仍然需要等待缓冲区已经收到了一切,因此IF需要是“我们收到了一切,但没有任何东西。”

谢谢!

HttpsURLConnection connection = null; 
BufferedReader reader = null; 

try { 
    URL url = new URL("https://example.com/GiveMeSomTextPlain"); 
    connection = (HttpsURLConnection) url.openConnection(); 
    connection.setConnectTimeout(9000); 
    connection.setReadTimeout(11000); 
    connection.connect(); 

    int resp = connection.getResponseCode(); 
    if (resp == 200) { 

     reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); 

     // if(reader.ThereWillBeNoData()){ // THIS IS WHAT I NEED 
      // ... 
     // } 

     String line = ""; 
     while((line = reader.readLine()) != null){ // EXCEPTION IF EMPTY DATA 
      // ... 
     } 

    }else{ 
     reader = new BufferedReader(new InputStreamReader(connection.getErrorStream())); 
    } 

} catch (IOException e) { 
    e.printStackTrace(); 
    // WE GET HERE AT EXCEPTION 
} finally { 
    if (connection != null) connection.disconnect(); 
    try { 
     if (reader != null) reader.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

编辑:啊,似乎它在超时结束(相当于我进入11S),但“空”是一个答案了,所以如何避免超时? (见我RESPONSE)

堆栈跟踪:

09-13 18:39:40.134 20925-21658/com.theapp D/ZZZ: BEFORE WHILE 
09-13 18:39:51.155 20925-21658/com.theapp W/System.err: java.net.SocketTimeoutException: Read timed out 
09-13 18:39:51.155 20925-21658/com.theapp W/System.err:  at com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method) 
09-13 18:39:51.155 20925-21658/com.theapp W/System.err:  at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:690) 
09-13 18:39:51.155 20925-21658/com.theapp W/System.err:  at java.io.BufferedInputStream.read(BufferedInputStream.java:283) 
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:  at com.android.okhttp.internal.http.UnknownLengthHttpInputStream.read(UnknownLengthHttpInputStream.java:39) 
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:  at java.io.InputStreamReader.read(InputStreamReader.java:233) 
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:  at java.io.BufferedReader.fillBuf(BufferedReader.java:145) 
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:  at java.io.BufferedReader.readLine(BufferedReader.java:397) 
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:  at com.theapp.Main.getMapData(Main.java:637) 
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:  at com.theapp.Main$2$2.run(Main.java:231) 
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:  at java.lang.Thread.run(Thread.java:841) 
09-13 18:39:51.165 20925-21658/com.theapp D/ZZZ: EXCEPTION 
+3

'readLine()'如果没有数据,则不会*抛出'IOException'。它返回null。你在说什么? – EJP

+0

你能发布异常堆栈跟踪吗? –

+0

它确实如果缓冲器从来没有任何数据,因为它正在等待。没有必要对自己进行测试而无需负面评价。我之前和之后都放了一些Log.d(),毫无疑问,发送一些数据的200会很好,但只要我在没有数据的情况下创建200,它就永远不会到达第二个Lod.d()过了一会儿,直接进入IOException。 – FlorianB

回答

0

原因的问题:

内容长度不是由服务器当没有数据发送。

这似乎是一个模棱两可的问题,因为在这种情况下是否应发送Content-Length并不是很清楚。 Web浏览器很好地处理了Content-Length的缺失,并且似乎假定它意味着0.然而,Android HttpsURLConnection不会,并且一直等到超时。我们可以认为,没有数据应该是一个204 HTTP响应代码,而不是200

因此,如果任何人有同样的问题:

  • 要么确保服务器发送的Content-Length:0时身体是空的

  • 或在这种情况下发送204。