Базовое консольное программирование на Java - можно использовать hasNextLine для чтения входов с консоли? - PullRequest
0 голосов
/ 19 февраля 2011

Мне подарили этот код, который мне кажется неестественным. Я бы обычно использовал hasNextLine() вместо логической переменной done, как показано в этом коде в цикле while, но теперь я запутался. У меня вопрос, могу ли я заменить логику, в которой переменная done отображается на hasNextLine(), когда ожидается ввод данных с консоли, или я могу использовать hasNextLine(), только если ввод поступает из файла? Как лучше реализовать этот код, когда ввод поступает из консоли, используя переменную done или hasNextLine()? Спасибо.

// TCPClient.java

import java.net.*;
import java.io.*;
import java.lang.*;

public class TCPClient{

    public static void main(String args[]){
    Socket clientSock=null;
    try{
        int port_num = Integer.valueOf(args[1]).intValue();  //get server's port no.
        clientSock = new Socket(args[0],(int)port_num);  // args[0] is the server host name

        /* String sock=clientSock.toString();
        System.out.println(sock); */

        PrintWriter oStream =
        new PrintWriter(clientSock.getOutputStream(),true);

        BufferedReader iStream =
        new BufferedReader(new InputStreamReader
                   (clientSock.getInputStream()));

        BufferedReader keyInput =
        new BufferedReader(new InputStreamReader(System.in));

        boolean done = false;
        String answer = iStream.readLine();
        if(answer != null)
        System.out.println(answer);

        while(!done){
        String line = keyInput.readLine();
        if(line.trim().equals("BYE"))
            done = true;
        oStream.println(line);
        answer = iStream.readLine();
        if(answer != null)
            System.out.println(answer);
        }

        clientSock.close();
    }catch(Exception e){
        System.out.println(e);
    }
    }
}

Ответы [ 2 ]

2 голосов
/ 19 февраля 2011

В решении @ Voo есть ошибка, поскольку nextLine() на keyInput также может возвращать null. Вот исправленная версия:

String line;
while ((line = keyInput.readLine()) != null && 
       !line.trim().equals("BYE")) {
    oStream.println(line);
    answer = iStream.readLine();
    if (answer != null) {
        System.out.println(answer);
    }
}

Могу ли я заменить логику, в которой указанная переменная отображается на hasNextLine(), когда ожидается ввод данных с консоли, или я могу использовать hasNextLine(), только если ввод поступает из файла?

Вы можете обернуть любой InputStream или любой Readable (из которых Reader является подтипом) в Scanner, что позволяет вам использовать hasNextLine() на всех них. Единственное предостережение в том, что hasNextLine() потенциально может блокировать неограниченное время ожидания ввода, если основной поток поступает из консоли, канала, сокета или аналогичного устройства.

Какой лучший способ реализации этого кода, когда ввод поступает из консоли, с использованием переменной done или hasNextLine()?

Любой из них подойдет, как и третий вариант, как показано выше. Это действительно вопрос вкуса ... и то, что вы думаете, выглядит проще всего. (Лично я бы не использовал Scanner просто , чтобы я мог позвонить hasNextLine() ... но это только мое мнение.)

Другое существенное различие между использованием Scanner и BufferedReader заключается в том, что Scanner скрывает любые IOException s, которые могут возникнуть при вызове hasNext...(), и возвращает просто false. Это хорошо для типичных сценариев использования Scanner в качестве облегченного синтаксического анализатора пользовательского ввода (как вы используете его на keyInput), но, возможно, не в других случаях использования.

2 голосов
/ 19 февраля 2011

Ну ваша идея и данное решение реализуют разные вещи.Данный код остается в цикле, пока вы не получите «BYE» из входного потока.В любом случае вашему решению сначала понадобится сканер или ваша собственная реализация hasNextLine (), поскольку у BufferedReader нет одного afaik.

Но если речь идет только об использовании логической переменной или нет, то альтернативой будет:

    String line;
    while(!(line = keyInput.readLine()).trim().equals("BYE")){
    oStream.println(line);
    answer = iStream.readLine();
    if(answer != null)
        System.out.println(answer);
    }

Я могу понять людей, которым не нравятся назначения в других выражениях, но я написал похожий код с проверкой переменной для! = NULL или EOF, потому что я нашел ее более читабельной.Я бы не стал делать это намного сложнее, чем то, что у вас есть сейчас, и в этом случае я бы, вероятно, использовал бы логическую переменную.

...