自包含Java控制台输入法?

时间:2014-02-04 18:44:14

标签: java exception console java.util.scanner bufferedreader

我正在尝试编写一个自包含的(即无需外部打开/关闭资源)方法来从控制台获取输入,但是遇到了多次使用它的问题。我使用BufferedReader和Scanner测试了它:

public class Test {

    public static void main(String[] args) {
//      String str1 = getConsoleInputSc("Enter the 1st string: ");
        String str1 = getConsoleInputBR("Enter the 1st string: ");
        System.out.println(str1);
//      String str2 = getConsoleInputSc("Enter the 2nd string: ");
        String str2 = getConsoleInputBR("Enter the 2nd string: ");
        System.out.println(str2);
    }

    public static String getConsoleInputBR(String prompt) {
        String input = "";
        try (BufferedReader bufferRead = new BufferedReader(
                new InputStreamReader(System.in))) {
            System.out.print(prompt);
            input = bufferRead.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return input;
    }

    public static String getConsoleInputSc(String prompt) {
        String input = "";
        try (Scanner scanIn = new Scanner(System.in)) {
            System.out.print(prompt);
            input = scanIn.nextLine();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
        return input;
    }    
}

我正在使用try-with-resources语句处理关闭资源。

以下是使用BufferedReader版本运行的示例:

Enter the 1st string: efsd
efsd
Enter the 2nd string: java.io.IOException: Stream closed
        at java.io.BufferedInputStream.getBufIfOpen(Unknown Source)
        at java.io.BufferedInputStream.read(Unknown Source)
        at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
        at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
        at sun.nio.cs.StreamDecoder.read(Unknown Source)
        at java.io.InputStreamReader.read(Unknown Source)
        at java.io.BufferedReader.fill(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at Test.getConsoleInputBR(Test.java:25)
        at Test.main(Test.java:16)

以下是使用扫描仪版本运行的示例:

Enter the 1st string: sdfds
sdfds
Enter the 2nd string: java.util.NoSuchElementException: No line found
        at java.util.Scanner.nextLine(Unknown Source)
        at Test.getConsoleInputSc(Test.java:3)
        at Test.main(Test.java:14)

我根据查找“java.util.NoSuchElementException:No line found”异常(带扫描程序)时发现的帖子尝试了一些建议。使用“while(scanIn.hasNextLine())...”我只是在第一次调用中得到一个连续循环。使用“if(scanIn.hasNextLine())”它在第二次调用中从不使它成为“input = scanIn.nextLine()”,因为if子句返回false。

我觉得这些问题与Java GC的不确定性有关,导致资源无法正确清理/释放,但这只是猜测。

有什么想法吗?

由于

2 个答案:

答案 0 :(得分:1)

Here's关于try-with-resources的教程。

声明以下内容时

try (BufferedReader bufferRead = new BufferedReader(
            new InputStreamReader(System.in))) {

当代码退出try块时,close()会在bufferRead上调用,close()会在包裹的InputStreamReader对象上调用close()System.in引用的对象上调用{{1}},基本上关闭标准输入。

在您确定不需要之前,请不要关闭标准输入,基本上不要。

你必须重新考虑你的设计。

答案 1 :(得分:1)

不要像你一样使用try-with-resources,只需将代码放在一个简单的try-catch块中,如下所示:

   public static String getConsoleInput(String prompt)
   {
      String input = "";
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      System.out.print(prompt);
      try {
         input = br.readLine();
      }
      catch (IOException e)
      {
         e.printStackTrace();
      }
      return input;
   }

当main()中的代码调用时,此方法工作正常。通过不使用try with resources,资源不会自动关闭。