0

So I wrote these two methods:

    public Player readPlayerData() {
        Player player = new Player();
        try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in))){
            System.out.println("What is your name?");
            player.setName(br.readLine());
            System.out.println("How much money do you have?");
            player.setBalance(BigDecimal.valueOf(Double.parseDouble(br.readLine())));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(player);
        return player;
    }

    public Currency readPlayerCurrency() {
        Currency currency = null;
        try(BufferedReader br2 = new BufferedReader(new InputStreamReader(System.in))){
            System.out.println("What is your currency?");
            currency = Currency.valueOf(br2.readLine());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(currency);
        return currency;
    }

When I call one at a time they work as intended, but when I call them after eachother I get a java.io.IOException: Stream closed. Does try with resources close the System.in input stream somehow or am I misunderstanding how it works?

menrva
  • 63
  • 7

2 Answers2

2

Does try with resources close the System.in input stream

Yes, it does. You should not close System.in input stream.

See:

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • How can i achieve this? Create a BufferedReader outside the try block and close it manually after? Would this leave the System.in input stream open? – menrva Mar 05 '20 at 17:43
  • @menrva No need to close `System.in` as the JVM will do it at termination. – Eng.Fouad Mar 05 '20 at 17:45
  • Sorry but I am still not understanding how this is working. If I use try with resources then it will close System.in instead of the JVM. In this case I can only use try with resources once during my application? Because if I use it after then the System.in stream will have already been closed? – menrva Mar 05 '20 at 17:51
  • @menrva Exactly. Once it is closed, you cannot use it again. Just keep it open and JVM will close it for you on process termination. – Eng.Fouad Mar 05 '20 at 17:54
  • @menrva You can always create one reader (or Scanner) wrapping at some point `System.in` in `main` method and pass it to other methods as argument. This way those methods will not have to create their own readers but will use one which was passed to them. At the end of main method (when application will end) you can explicitly close it. – Pshemo Mar 05 '20 at 17:56
0

The try-with-reource main function is to automatically close the resource - this is not wanted for System.in, so use just a normal try-catch statement as in:

public Player readPlayerData() {
    Player player = new Player();
    try {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("What is your name?");
        player.setName(br.readLine());
        System.out.println("How much money do you have?");
        player.setBalance(BigDecimal.valueOf(Double.parseDouble(br.readLine())));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println(player);
    return player;
}

(not tested, just an example to show how it looks like)

(eventually better have the method throws the exception instead of handling it)

user85421
  • 28,957
  • 10
  • 64
  • 87