【问题标题】:BufferedReader Closes at the Beginning of a For-Loop in JavaBufferedReader 在 Java 中的 For 循环开始时关闭
【发布时间】:2020-10-31 10:55:01
【问题描述】:

我正在使用 BufferedReader 在 for 循环中接收多个输入;但是,当第一次输入时,它会抛出错误

java.io.Exception:流已关闭

尽管我直到 for 循环结束后才关闭它。代码如下:

        BufferedReader menu = new BufferedReader(new InputStreamReader(System.in));
        for (int i = 0; players.length > i; i++) {
            System.out.println("Choose the " + i + " player");
            System.out.println("1. New Player");
            System.out.println("2. Old Player");
            int choice2 = Integer.parseInt(menu.readLine());
            System.out.println("Which team are you on?");
            int playersTeam = Integer.parseInt(menu.readLine());
            Person player = new Person();
            if (choice2 == 1) {
                player.squadFilling();
                player.playerNaming();
            } else if (choice2 == 2) {
                break;
            }
        }
        menu.close();

是什么导致了崩溃,我该如何解决?感谢您的宝贵时间!

堆栈跟踪:

java.io.IOException: Stream closed
    at java.base/java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:168)
    at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:334)
    at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297)
    at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
    at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188)
    at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181)
    at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
    at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
    at Main.main(Main.java:409)

【问题讨论】:

  • 这个错误是在for循环的第一次迭代之后产生的,还是在这段代码已经被调用一次之后的第一次迭代产生的?
  • for循环的第一次迭代。
  • System.in 是否可能在此调用之前已在另一个代码块中关闭?当您关闭使用 System.in 作为 InputStream 的 Reader 时,该 InputStream 也会关闭。这意味着您不能再次使用 System.in,直到它再次被实例化。
  • 什么意思?打开新的System.in 不会打开新的 InputStream 吗?
  • @FrasherGray - 不是这段代码(您发布的)导致了这种情况。我怀疑您程序的其他部分正在关闭System.in。如果您已从程序中的每个位置删除了close() 语句,则您可能在一些关闭System.in 的try-with-resources 代码中使用了System.in

标签: java bufferedreader java-io


【解决方案1】:

在 Java 8 中,它不会抛出任何异常(尝试相同的代码)。它工作正常。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {

 public static void main(String[] args) throws NumberFormatException, IOException {

    BufferedReader menu = new BufferedReader(new InputStreamReader(System.in));
    for (int i = 0; 2 > i; i++) {
                    System.out.println("Choose the " + i + " player");
                    System.out.println("1. New Player");
                    System.out.println("2. Old Player");
                    int choice2 = Integer.parseInt(menu.readLine());
                    System.out.println("Which team are you on?");
                    int playersTeam = Integer.parseInt(menu.readLine());
                    if (choice2 == 1) {
                        continue;
                    } else if (choice2 == 2) {
                        break;
                    }
                    
    }
    menu.close();
 }
}

【讨论】:

  • 嗯。不过,这并不是真正的答案
  • Main.java:409 中的哪一行?
【解决方案2】:

我认为您应该尝试将menu.close(); 移动到最后调用的不同方法。以及将BufferedReader menu 移出该方法以提高可见性,并在方法中使用menu = new BufferedReader(new InputStreamReader(System.in));

BufferedReader menu;
void method(){
    menu = new BufferedReader(new InputStreamReader(System.in));
    for (int i = 0; players.length > i; i++) {
        System.out.println("Choose the " + i + " player");
        System.out.println("1. New Player");
        System.out.println("2. Old Player");
        int choice2 = Integer.parseInt(menu.readLine());
        System.out.println("Which team are you on?");
        int playersTeam = Integer.parseInt(menu.readLine());
        Person player = new Person();
        if (choice2 == 1) {
            player.squadFilling();
            player.playerNaming();
        } else if (choice2 == 2) {
            break;
        }
    }
    cleanup();
}

这允许我们创建一个方法 cleanup()。

private void cleanup(){
    menu.close();
}

我认为这可能会有所帮助的原因是我相信 menu.close() 正在被调用,而作者仍在完成最后一个循环。我认为添加 cleanup() 作为单独的方法会起作用。

【讨论】:

    【解决方案3】:

    我错过了一些放在代码中其他位置的.close() 命令。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-25
      • 2021-02-20
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 2020-02-02
      • 1970-01-01
      相关资源
      最近更新 更多