InputStreamReader ready() перед чтением неправильно возращает результат

122
19 октября 2019, 15:40

Когда программа ещё не читала из потока, метод ready() вернёт false, хотя на самом деле в потоке есть что читать. А если один раз прочитать, то дальше ready() работает правильно. Почему так получается? Вот пример программы:

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.net.Socket;
import java.io.IOException;
import java.util.*;
public class Server {
    public static void main(String[] args) {
        try {
            String ip = "";  //любой работающий веб сервер
            int port = 25;  //любой
            Socket socket = new Socket(ip, port);
            InputStreamReader reader = new InputStreamReader(socket.getInputStream());
            String str = "";
            System.out.println(reader.ready());
            str += (char) reader.read();
            System.out.println(reader.ready());
            while(reader.ready()) {
                str += (char) reader.read();
            }
            System.out.println("End read - " + str);
            reader.close();
            socket.close();
        }
        catch(IOException exp) {
            System.out.println("Error");
        }
    }
}
Answer 1

Из документации:

Tells whether this stream is ready to be read. An InputStreamReader is ready if its input buffer is not empty, or if bytes are available to be read from the underlying byte stream.

Overrides:

ready in class Reader

Returns:

True if the next read() is guaranteed not to block for input, false otherwise. Note that returning false does not guarantee that the next read will block.

Throws:

IOException - If an I/O error occurs

Согласно этому, данные до чтения скорее всего заблокированы и доступны после начала чтения. Та же ситуация была у меня при чтении сериализованных объектов из файла.

Вообще не рекомендуется делать проверку на наличие данных через ready(), так как этот метод не для этого. Лучше проверять, что read() возвращает значение, если вернет -1, значит данных больше нет.

Например как при использовании BufferedReader, проверяется вернул ли метод readline() новую строку.

String line = in.readLine();
while(line != null){
   ...
   line = in.readLine();
}
READ ALSO
Составить regex для поиска одинаковых букв в начале и конце слова

Составить regex для поиска одинаковых букв в начале и конце слова

Напечатать без повторения слова текста, у которых первая и последняя буквы совпадаютНужно составить регулярное выражение

84
generic в kotlin

generic в kotlin

Хочу сделать клас более гибким при помощи generics в kotlinРанее использовал их только в java и в очень примитивных случаях

110
Ошибка при отправке JSON пакета с jQuery на Java Spring RestController

Ошибка при отправке JSON пакета с jQuery на Java Spring RestController

При отправки JSON пакета с отдельного HTML файла на Java Spring RestController при помощи jQuery, java выдает предупреждение :

101
Java Hibernate PersistenceBag

Java Hibernate PersistenceBag

Как заставить хибер возвращать не PersistenceBag, а list или set?

117