【问题标题】:Java basic console programming - can use hasNextLine to read inputs from console?Java 基本控制台编程 - 可以使用 hasNextLine 从控制台读取输入吗?
【发布时间】:2011-02-19 01:37:19
【问题描述】:

我收到了这段对我来说看起来不自然的代码。我通常会使用hasNextLine() 而不是布尔变量done,如while 循环中的这段代码所示,但现在我很困惑。我的问题是,当需要从控制台输入时,我可以用hasNextLine() 替换变量done 显示的逻辑,还是只能在输入来自文件时使用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);
    }
    }
}

【问题讨论】:

  • 对不起,您的问题与套接字无关。
  • 当您在示例程序中使用套接字时,问题是关于控制台输入(以及接受的答案)。

标签: java input console


【解决方案1】:

@Voo 的解决方案中有一个错误,因为keyInput 上的nextLine() 也可能返回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() 替换显示变量done 的逻辑,还是只能在输入来自文件时使用hasNextLine()

您可以将任何InputStream 或任何Readable(其中Reader 是一个子类型)包装在Scanner 中,从而允许您在所有这些上使用hasNextLine()。唯一需要注意的是,如果底层流来自控制台、管道、套接字或类似的,hasNextLine() 可能会无限期地阻塞等待输入。

在输入来自控制台的情况下,使用done 变量或hasNextLine() 实现此代码的更好实践方法是什么?

两者都可以,如上图所示的第三个选项。这真的是一个品味问题......你认为看起来最简单。 (就我个人而言,我不会使用Scanner 只是,这样我就可以打电话给hasNextLine() ...但这只是我的意见。)

使用ScannerBufferedReader 之间的另一个显着区别是Scanner 隐藏了在调用hasNext...() 时可能出现的任何IOExceptions,并仅返回false。这对于 Scanner 作为轻量级用户输入解析器的典型用例来说是一件好事(就像您在 keyInput 上使用它一样),但在其他用例中可能不是。

【讨论】:

  • 是的,你是对的,我是过失。需要注意的是:我们都改变了程序的语义。正确的解决方案是 do - while 循环。
【解决方案2】:

你的想法和给定的解决方案实现了不同的东西。给定的代码会一直停留在循环中,直到您从输入流中获得“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,因为我发现它更易读。我不会让它比你现在得到的复杂得多,在这种情况下我可能会使用布尔变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多