如何解决流阅读问题?

时间:2019-05-28 13:27:08

标签: java scala

我正在尝试从发送JSON正文的URL中读取响应。但是我的代码无法读取完整的响应。我的代码有问题,但我没有得到。

val url: URL = new URL("https://jsonplaceholder.typicode.com/todos/1")
val httpsConnection: HttpsURLConnection = url.openConnection().asInstanceOf[HttpsURLConnection]
httpsConnection.setRequestMethod("GET")
httpsConnection.setRequestProperty("Accept", "application/json")
httpsConnection.setRequestProperty("Accept-Language", "en_US")
val streamReader: InputStreamReader = new InputStreamReader(httpsConnection.getInputStream)
val bufferedReader = new BufferedReader(streamReader)
val stringBuffer: StringBuffer =new StringBuffer()
while(bufferedReader.readLine() != null){
  stringBuffer.append(bufferedReader.readLine())
}

println(stringBuffer.toString)

上面的代码没有给我实际的结果。 但是,如果我避免使用常规的Java样式并使用scala源:

Source.fromInputStream(httpsConnection.getInputStream,"UTF8").getLines().foreach(println)

这给出了实际的JSON。

我的第一部分代码有什么问题?

3 个答案:

答案 0 :(得分:3)

在这个地方:

while(bufferedReader.readLine() != null){
  stringBuffer.append(bufferedReader.readLine())
}

您要先两次致电readLine来检查它是否不为null,然后再附加到stringBuffer上。但是实际上,第二个呼叫获得了另一条线路,因此您失去了第二条线路。

在Java中读取缓冲流的常用方法是:

String line;

while ((line = r.readLine()) != null) {
   // do your stuff...
}

但是Scala中的分配会返回Unit,因此它将无法正常工作。

所以也许可以使用Stream.continually吗?

Stream
    .continually(bufferedReader.readLine())
    .takeWhile(_ != null)
    .foreach(stringBuffer.append)

答案 1 :(得分:1)

我知道这并不是您要找的东西,但是数据操作有时会非常复杂,尤其是在涉及网络时。因此,为了简便起见,我建议使用外部库从JSON读取URL文件。

以下代码使用JSON.simpleApache Commons IO提供的方法从您提供的链接中检索JSON文件:

public void getJson() throws IOException {

    java.net.URL url = new java.net.URL("https://jsonplaceholder.typicode.com/todos/1");
    String json = IOUtils.toString(url, Charset.forName("UTF-8"));
    System.out.println(json);
}

答案 2 :(得分:1)

readLine被调用两次,并且InputStreamReader应该使用源的字符集。 我在这里采用了ISO-8859-1,因为它不会像UTF-8那样给出错误。 同样,readLine会删除行尾,而StringBuilder更快。

val streamReader: InputStreamReader = new InputStreamReader(httpsConnection.getInputStream,
    "ISO-8859-1")
val bufferedReader = new BufferedReader(streamReader)
val stringBuilder: StringBuilder = new StringBuilder()
while (true) {
  val line = bufferedReader.readLine();
  if (line == null) {
      break;
  }
  stringBuilder.append(line).append("\r\n");
}