1

I am modding Minicraft, and I am running into a bit of trouble using BufferedReaders.

So in my mod, I have a class called FuncResource in which I define a way to execute a custom method when an item is used.
In the Resource vanilla class, I define multiple objects of this type. For example, a console object which lets you change your gamemode.
Here is the interact method I am using in the console item class:

public boolean interact(Tile tile, Level level, int x, int y, Player player, int direction)
{
    InputStreamReader isr = new InputStreamReader(System.in);

    BufferedReader reader = new BufferedReader(isr);

    String input = "";

    System.out.print("> ");

    try
    {
        input = reader.readLine();
        reader.close();
    }
    catch(IOException e)
    {
        System.out.println("Input error...  :/");
    }

    String[] commandList = input.split(" ");

    if(commandList[0].equals("gamemode"))
    {
        player.gamemode = Integer.parseInt(commandList[1]);
        return true;
    }

    return false;
}

Now here's the problem: Using the console item once, it's fine. I change my gamemode. HOWEVER, when I use it every time after that, it always throws an IOException. Every single time.

Am I doing something wrong? Have I messed up the input somehow? Please help - I've read the JavaDocs and they didn't help, and I'm an amateur at Java.
If you need more information, just ask.

EDIT: I took people's advice and removed the reader.close(); code. HOWEVER, I tried it again and it printed this stacktrace:

java.io.IOException: Stream closed
    at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:162)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:325)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:154)
    at java.io.BufferedReader.readLine(BufferedReader.java:317)
    at java.io.BufferedReader.readLine(BufferedReader.java:382)
    at com.mojang.ld22.item.resource.funcitems.ConsoleItem.interact(ConsoleItem.java:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.mojang.ld22.item.resource.FuncResource.interactOn(FuncResource.java:31)
    at com.mojang.ld22.item.ResourceItem.interactOn(ResourceItem.java:53)
    at com.mojang.ld22.entity.Player.attack(Player.java:177)
    at com.mojang.ld22.entity.Player.tick(Player.java:118)
    at com.mojang.ld22.level.Level.tick(Level.java:274)
    at com.mojang.ld22.Game.tick(Game.java:221)
    at com.mojang.ld22.Game.run(Game.java:165)
    at java.lang.Thread.run(Thread.java:744)
Atutouato
  • 375
  • 4
  • 13
  • Can you post the stack trace that points to the line of code that caused the error? – Taylor Hx Jan 20 '14 at 02:23
  • There's lots of reasons it might throw an exception. Have you considered actually printing the exception using something like `e.printStackTrace()` for example – MadProgrammer Jan 20 '14 at 02:23
  • Hm. One second, I'll print the stack trace... – Atutouato Jan 20 '14 at 02:24
  • Printed the stack trace. I don't know why on Earth it's throwing that error, though... Why would the stream be closed? – Atutouato Jan 20 '14 at 02:31
  • Since eventually someone will mention [CloseShieldInputStream](http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/CloseShieldInputStream.html) I will go ahead and post a comment :D. Just wrap `System.in` with it and close the `Scanner` as intended. – Anthony Accioly Jan 20 '14 at 02:38
  • @AnthonyAccioly, I have no idea what that is. BUT, I will go ahead, look it up, and try to use it anyways. – Atutouato Jan 20 '14 at 02:40
  • Actually, @AnthonyAccioly, I want to do this without any external libraries. Sorry. – Atutouato Jan 20 '14 at 02:43
  • If you are still getting the exception, verify you aren't closing the stream somewhere else and also make sure you've truly recompiled the code. – Radiodef Jan 20 '14 at 03:00
  • I have really truly recompiled the code. `reader` is a local variable, and I have searched and double-searched my file twice over, and there is no reference to the stream being closed. – Atutouato Jan 20 '14 at 03:10

3 Answers3

3
try
{
    input = reader.readLine();
    reader.close();
}
catch(IOException e)
{
    System.out.println("Input error...  :/");
}

Don't close this reader because it contains System.in which should remain open.

fgb
  • 18,439
  • 2
  • 38
  • 52
3

Closing your reader will close the underlying stream; closing System.in is, in general, bad, as you can imagine.

As a general rule, if you opened something, close it; but if you didn't, don't. Here: don't'.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
0

I cannot remember what I did, but I solved it. I had removed the reader.close(); statement and it still wasn't working properly, but just one time it simply worked. I don't know how or why, but thanks to all who helped.

Atutouato
  • 375
  • 4
  • 13