Как я могу решить эту проблему чтения потока? - PullRequest
1 голос
/ 28 мая 2019

Я пытаюсь прочитать ответ с URL-адреса, отправляющего тело JSON. Но мой код не может прочитать полный ответ. В моем коде проблема, но я ее не понимаю.

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 ]

3 голосов
/ 28 мая 2019

В этом месте:

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

вы сначала набираете readLine дважды, чтобы проверить, не является ли оно нулевым, затем добавляете к 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 голос
/ 28 мая 2019

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");
}
1 голос
/ 28 мая 2019

Я знаю, что это не совсем то, что вы ищете, но манипулирование данными иногда может быть довольно сложным, особенно когда вы используете сети.Поэтому для простоты я бы порекомендовал использовать внешние библиотеки для чтения файла JSON из URL.

. Следующий код извлекает ваш файл JSON по предоставленной вами ссылке, используя методы, предоставленные * 1006.* JSON.simple и Apache Commons IO :

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...