如何使用java应用程序“重置”或“清除”System.in?

时间:2014-09-11 21:44:35

标签: java bash

我正在运行一个类似下面的Java应用程序:

InputStreamReader isReader = new InputStreamReader(System.in);
BufferedReader bufReader = new BufferedReader(isReader);
while (true) {
    try {
        String inputStr = null;
        if ((inputStr=bufReader.readLine()) != null) {
            //DO SOMETHING
        }
        else {
            System.out.println("input is null");
        }
    }
    catch (Exception e) {
        //DO SOMETHING
    }
}

使用此命令java test < textfilename 但读完所有内容后,应用程序开始继续打印input is null。当然我可以在break;下添加System.out.println("input is null");,但有没有办法可以清除输入缓冲区并开始从命令行输入?

PS:我正在使用的文件示例:

11111111
11111112
11111113
11111114

3 个答案:

答案 0 :(得分:2)

据我所知,这是不可能的。当您在命令行中使用<从文件中读取时,System.in的内容由shell控制,而不是由Java控制。

readLine()返回null是Java表示您已经到达文件末尾的方式,也是您发送EOF /类型Ctrl-D时获得的方式在shell中。

答案 1 :(得分:1)

您无法重定向输入或输出,并且可以访问普通控制台System.in。来自docs(强调我的):

  

虚拟机是否具有控制台取决于底层平台以及虚拟机的调用方式。如果从交互式命令行启动虚拟机而不重定向标准输入和输出流,则其控制台将存在,并且通常将连接到启动虚拟机的键盘和显示器。 / p>

也就是说,只需对代码进行最少的更改,您仍然可以在很大程度上完成您想要的任务。

public static void main(String args[]) throws FileNotFoundException {
    readFile(args[0]);
    // Continue normal console input here
}

private static void readFile(String filename) throws FileNotFoundException {
    InputStream original = System.in;
    System.setIn(new FileInputStream(filename)); // VM trickery

    try (BufferedReader bufReader = new BufferedReader(new InputStreamReader(System.in))) { 
        String inputStr = null;
        while ((inputStr = bufReader.readLine()) != null) { // stops loop on `null`
            System.out.println(inputStr);
        }
    } catch (IOException e) { 
        e.printStackTrace();
    }

    System.setIn(original); // more VM trickery
}

主要变化:

  • 使用输入文件的文件名作为第一个参数调用,即java test textfilename
  • 使用FileInputStream
  • 使用try-with-resources确保我添加的FileInputStream已关闭
  • 处理readLine()的空值返回,而不是无限循环null

答案 2 :(得分:0)

也许是这样的:

InputStreamReader isReader = new InputStreamReader(System.in);
BufferedReader bufReader = new BufferedReader(isReader);
String inputStr = null;
try {
   while ((inputStr=bufReader.readLine()) != null) {
   //DO SOMETHING
   }
}catch (Exception e) {
//DO SOMETHING
}