简体   繁体   English

在Java中多次读取System.in会导致IOException?

[英]Reading System.in multiple times in Java causes IOException?

I am playing around trying to create a little command line game to reinforce some of the things I have learnt in Java over the last few months. 我正在努力创建一个小命令行游戏,以加强我在过去几个月里用Java学到的一些东西。

I am trying to create a method called readInput() which returns a String which I can call again and again. 我正在尝试创建一个名为readInput()的方法,该方法返回一个我可以反复调用的String。 The first time it works perfectly, the second time however it causes an IO.Exception. 第一次它完美地工作,第二次它会导致IO.Exception。 If I remove the statement bisr.close(); 如果我删除语句bisr.close(); it works but was taught to close streams as it is bad practice to leave them open. 它有效,但被教导要关闭溪流,因为将它们打开是不好的做法。

Can someone kindly point me in the right direction as I have googled but to no avail. 有人可以指出我正确的方向,因为我用谷歌搜索但无济于事。

The method ... 方法 ...

private String readInput()
{
    String input = null;
    BufferedReader bisr = null;
    try
    {
        bisr = new BufferedReader(new InputStreamReader(System.in));
        input = bisr.readLine();
    }
    catch (Exception e)
    {
        System.out.println("Error: " + e);
    }
    finally
    {
        try
        {
            bisr.close();
        }
        catch (Exception e)
        {
            System.out.println("Error:" + e);
        }
        return input;
    }
}

The first time it works perfectly, the second time however it causes an IO.Exception 第一次它完美地工作,第二次它会导致IO.Exception

bisr.close() will also close the underlying input stream (in this case System.in ). bisr.close()也将关闭底层输入流 (在本例中为System.in )。 This is why consecutive reads will result in an IOException. 这就是连续读取将导致IOException的原因。

If I remove the statement bisr.close(); 如果我删除语句bisr.close(); it works but was taught to close streams as it is bad practice to leave them open 它有效,但被教导要关闭溪流,因为将它们打开是不好的做法

No problem in keeping System.in open for the duration of the execution. 在执行期间保持System.in保持打开没有问题。

If you don't want to create unnecessarily many objects, you can create the BufferedReader once, and pass that around. 如果您不想创建不必要的许多对象,可以创建一次BufferedReader,然后传递它。

For this particular situation, I would probably just go with 对于这种特殊情况,我可能会选择

private String readInput() {
    return new Scanner(System.in).nextLine();
}

The problem is that closing the BufferedReader also automatically closes the InputStreamReader which implicitly closes System.in . 问题是关闭BufferedReader还会自动关闭隐式关闭System.inInputStreamReader

And the second time you call that method System.in is closed, which means you won't be able to read from it. 并且第二次调用该方法时, System.in将关闭,这意味着您将无法从中读取。

The "always close it" only really applies to resources that you also opened! “永远关闭它”只适用于您也打开的资源!

For System.in it is better to have a global BufferedReader or Scanner you create once. 对于System.in,最好拥有一次创建的全局BufferedReader或Scanner。 This is because a BufferedReader and Scanner can read more than one line which it buffers for performance so you could be discarding some lines or parts of lines. 这是因为BufferedReader和Scanner可以读取多行缓冲性能,因此您可能会丢弃某些行或部分行。

public static void main(String... args) throws  InterruptedException {
  for(int i=0;i<5;i++) {
    System.out.println("\nread "+readLine());
    // give me time to write more than one line, no problem from a file.
    Thread.sleep(1000);
  }
}

public static String readLine() {
  // can lose input.
  return new Scanner(System.in).nextLine();
}

if I enter the numbers 1,2,3 etc across the keyword quickly. 如果我快速输入关键字的数字1,2,3等。

1

read 1
2
3
4
read 2

5
6
7
read 4

8
9
0
read 7

-
=

read 0

If I use a global Scanner object and do the same thing. 如果我使用全局Scanner对象并执行相同的操作。

static final Scanner IN = new Scanner(System.in);

public static void main(String... args) throws InterruptedException {
  for (int i = 0; i < 10; i++) {
    System.out.println("\nread " + readLine());
    // give me time to write more than one line, no problem from a file.
    Thread.sleep(1000);
  }
}

public static String readLine() {
  return IN.nextLine();
}

prints 版画

1

read 1
2
3
4
read 2

5
6
read 3

7
8

read 4
9

read 5
0

read 6

read 7

read 8

read 9

read 0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM