-1

I'm writing a sort of program that records data and exports it to an external file. In my main class, I have this loop that prompts you at the end of the program if you want to restart the program or terminate it. I don't know why though but when I added a choice to clear a particular log file generated by the program, it skips the BufferedReader at the end of the program that prompts the user whether to restart or terminate and throws an IOException instead. What's wrong with my code?

Main class:

    package com.record.project;

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

public class Main {

    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(System.in);

        System.out
                .println("Display records, enter data, or edit records file? (a , b, c)");

        String choice = input.nextLine();

        Choice.sort(choice);

        try {
            Main.loop();
        } catch (IOException e) {

            e.printStackTrace();
            System.out.println("Main main error");

        }

        System.out.println("Program complete.");
        input.close();

    }

    public static void loop() throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Program body complete.");
        System.out
                .println("Restart program or terminate? (restart, terminate)");
        String choice = br.readLine();
        switch (choice) {
        case "restart":
            loopA: while (1 < 2) {

                System.out
                        .println("Display records, enter data, or edit records file? (a , b, c)");

                String choice1 = br.readLine();

                Choice.sort(choice1);

                System.out.println("Program body complete.");
                System.out
                        .println("Restart program or terminate? (restart, terminate)");
                String choice2 = br.readLine();
                if (choice2.equals("terminate")) {
                    break loopA;
                }

                System.out.println("Program terminated.");
                break;
            }
            break;

        case "terminate":
            System.out.println("Program terminated.");
            System.out.println("Program complete.");
            System.exit(1);
            break;

        default:
            System.out.println("Invalid answer.");
            System.exit(1);
            break;
        }

    }

}

When I run it, this is the output: input = user input

Display records, enter data, or edit records file? (a , b, c)
*input*clearlog
Clear all logs or specific?(all, specific)
*input*all
Program body complete.
Restart program or terminate? (restart, terminate)
java.io.IOException: Stream closed
Main main error
Program complete.
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 com.record.project.Main.loop(Main.java:40)
at com.record.project.Main.main(Main.java:21)

For those that do want to see, here is the method where the Logging takes place:

Logger class clearLog method:

    @SuppressWarnings("resource")
    public static void clearLog() {
    System.out.println("Clear all logs or specific?(all, specific)");
    try (BufferedReader br = new BufferedReader(new InputStreamReader(
            System.in))) {

        File fileR = new File("read.log");
        File fileW = new File("write.log");
        File fileC = new File("clear.log");

        BufferedWriter frR = new BufferedWriter(new FileWriter(fileR));
        BufferedWriter frW = new BufferedWriter(new FileWriter(fileW));
        BufferedWriter frC = new BufferedWriter(new FileWriter(fileC));

        String choice = br.readLine();
        switch (choice) {
        case "all":
            frR.write("");
            frW.write("");
            frC.write("");
            break;

        case "specific":
            System.out.println("Which file? (read, write, clear)");
            String fileDel = br.readLine();
            switch (fileDel) {
            case "read":
                frR.write("");
                break;

            case "write":
                frW.write("");
                break;

            case "clear":
                frC.write("");
                break;

            default:
                System.out.println("Invalid answer.");
                break;

            }

        default:
            System.out.println("Invalid answer.");
            break;

        }

    } catch (IOException e) {
        e.printStackTrace();
        System.out.println("Logger error.");
    }

}
Lexicographical
  • 501
  • 4
  • 16
  • 3
    When you post a question, please create a minimal example that illustrates your issue. No one wants to read through your entire application to hunt down the parts of the program that are not working. You should make things as easy as possible for the reader to ensure quick responses. – thatidiotguy Sep 19 '14 at 17:05
  • 1
    The great thing about exceptions is that they (usually) tell you what went wrong. – Sotirios Delimanolis Sep 19 '14 at 17:05
  • 2
    Also, http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java – Sotirios Delimanolis Sep 19 '14 at 17:07
  • @thatidiotguy Sorry. I updated the code so it's just the main class file. – Lexicographical Sep 19 '14 at 17:08
  • Can you post the stack trace? – clever_trevor Sep 19 '14 at 17:09
  • @SotiriosDelimanolis Oh ok thanks. I didn't notice that, I fixed it but the error still persists. I tried reading the exception but I can't find what's wrong. – Lexicographical Sep 19 '14 at 17:13
  • @clever_trevor I editted it. The stacktrace is posted at the bottom. – Lexicographical Sep 19 '14 at 17:17
  • 3
    Please post the *exception*. The stack trace is meaningless without it. – user207421 Sep 19 '14 at 17:17
  • It's an IOException ._. – Lexicographical Sep 19 '14 at 17:21
  • @JavaFanatic: I'm sure it's got a *message* too... – Jon Skeet Sep 19 '14 at 17:21
  • I'm having trouble finding exactly where the problem is. Maybe you could debug it and tell us which line is throwing the error? Also, you are ignoring the terminate condition of while loops by having it be (1 < 2). Maybe implement something that terminates more unexpectedly. – clever_trevor Sep 19 '14 at 17:21
  • Additionally, it would really help if you would format your code. Hopefully it doesn't look like this in your IDE/editor - if it does, see if your IDE/editor has an option to reformat it all for you. – Jon Skeet Sep 19 '14 at 17:22
  • Exceptions come with a message. Why are you so intent on keeping it a secret? Nobody can help you until you disclose it. – user207421 Sep 19 '14 at 17:22
  • Sorry I didn't get what you meant the first time. It says Print stream closed. I can't find where it was closed though. – Lexicographical Sep 19 '14 at 17:28
  • That's not the actual output. The message would come immediately before the stack trace, not two lines earlier. It is also apparent that this isn't the real code either. Somewhere you are closing the BufferedReader. – user207421 Sep 19 '14 at 17:31
  • That was the output. If you're wondering about the Main main error thing, it was what I placed to signify that the exception occurred in the Main class in the main method by putting e.printStackTrace() then doing System.out.println("Main main error"); I also checked all the other classes and I didn't close the BufferedReader. – Lexicographical Sep 19 '14 at 17:34

1 Answers1

2

Your problem is that System.in has already been closed when you try to read from it. It's getting closed by the try-with-resources in clearLog(), since that's what try-with-resources does. If you don't want to do that, you should declare the BufferedReader in clearLog() as a regular variable instead.

Or, better yet, you could create a single BufferedReader, and read from it in all your methods, instead of creating new ones all over the place.

Tim
  • 2,027
  • 15
  • 24