Почему readLine () приводит к неопределенной ошибке с InputStreamReader? - PullRequest
0 голосов
/ 10 января 2020

Я создаю простой клиент IR C в Java. Я столкнулся с проблемой при попытке прочитать поток данных с сервера, используя InputStreamReader, завернутый в BufferedReader. Все примеры, которые я нашел, используют метод readLine () для сбора данных. Однако при использовании этого подхода я получаю следующую ошибку:

readLine () не определен для типа InputStreamReader

Ошибка впервые появляется в моем while l oop. Вот код:

public class IRCClient {

    //Initialize the input and output streams
    private Socket socket               = null;
    private InputStreamReader reader    = null; //What we receive from the host
    private OutputStreamWriter writer   = null; //What we send to the host

        //Client constructor
    public IRCClient(String address, int port, String nick, String login, String channel) {

        //Establish a connection to the host
        try
        {
            socket = new Socket(address, port);

            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(socket.getOutputStream()));

            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
        }
        catch(UnknownHostException u)
        {
            System.out.println(u);
        }
        catch(IOException i)
        {
            System.out.println(i);
        }

        //Login to the host
        try
        {
            writer.write("NICK " + nick + "\r\n");
            writer.write("USER " + login + "\r\n");
            writer.flush();
        }
        catch(IOException i)
        {
            System.out.println(i);
        }

        //Read lines from the server to make sure we are connected
        String line = null;
        try
        {
            while ((line = reader.readLine()) != null) {

                if (line.indexOf("004") >= 0) {
                    // We are logged in
                    break;
                } else if (line.indexOf("433") >= 0) {
                    System.out.println("Nickname is already in use");
                    return;
                }
            }
        } catch (IOException i) {
            System.out.println(i);
        }

        // Join the specified channel
        writer.write("JOIN " + channel + "\r\n");
        writer.flush();

        // Keep reading lines from the host.
        while ((line = reader.read()) != null) {
            if (line.toLowerCase().startsWith("PING ")) {
                //Respond with PONG tro avoid being disconnected
                writer.write("PONG " + line.substring(5) + "\r\n");
                writer.flush();
            }
            else {
                //Print the line received
                System.out.println(line);
            }
        } //end while
    }

    //Instantiate the client object
    public static void main(String[] args){

        //Connection details
        String serverAddress    = "irc.chat.twitch.tv";
        int serverPort      = 6667;
        String nick         = args[0];
        String login        = args[1];
        String channel      = args[2];

        IRCClient client = new IRCClient(serverAddress, serverPort, nick, login, channel);
    } //end main

} //end class

Ответы [ 2 ]

3 голосов
/ 10 января 2020

Проблема здесь в том, что переменные reader и writer не видны в то время как l oop, а только в блоке try-catch, в котором они объявлены.

Если Вы изменяете свой код следующим образом: он должен по крайней мере компилироваться (не проверял id, потому что у меня нет серверной реализации):

//Client constructor
public IRCClient(String address, int port, String nick, String login, String channel) throws IOException {//EDITED HERE added throws declaration (either do this, or catch the exceptions)


//Client constructor
public IRCClient(String address, int port, String nick, String login, String channel) throws IOException {//EDITED HERE added throws declaration (either do this, or catch the exceptions)

    //Establish a connection to the host
    //EDITED HERE move the declaration here to have the variables visible
    BufferedWriter writer = null;
    BufferedReader reader = null;
    try {
        socket = new Socket(address, port);

        writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

        reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    }
    catch (UnknownHostException u) {
        System.out.println(u);
    }
    catch (IOException i) {
        System.out.println(i);
    }

    //Login to the host
    try {
        writer.write("NICK " + nick + "\r\n");
        writer.write("USER " + login + "\r\n");
        writer.flush();
    }
    catch (IOException i) {
        System.out.println(i);
    }

    //Read lines from the server to make sure we are connected
    String line = null;
    try {
        while ((line = reader.readLine()) != null) {

            if (line.indexOf("004") >= 0) {
                // We are logged in
                break;
            }
            else if (line.indexOf("433") >= 0) {
                System.out.println("Nickname is already in use");
                return;
            }
        }
    }
    catch (IOException i) {
        System.out.println(i);
    }

    // Join the specified channel
    writer.write("JOIN " + channel + "\r\n");
    writer.flush();

    // Keep reading lines from the host.
    while ((line = reader.readLine()) != null) {//EDITED HERE replaced read() with readLine()
        if (line.toLowerCase().startsWith("PING ")) {
            //Respond with PONG tro avoid being disconnected
            writer.write("PONG " + line.substring(5) + "\r\n");
            writer.flush();
        }
        else {
            //Print the line received
            System.out.println(line);
        }
    } //end while
}

Я пометил части, которые я изменил, комментарием //EDITED HERE

2 голосов
/ 10 января 2020

Вы не инициализируете поля, вы создаете неиспользуемые локальные переменные, и ваши поля имеют неправильный тип.

Измените

private InputStreamReader reader    = null; //What we receive from the host

на

private BufferedReader reader;

И измените

BufferedReader reader = new BufferedReader(

на

reader = new BufferedReader(

У вас будет похожая проблема с писателем. Для этого сделайте подобное.

...