M
M
martin_bleat2021-05-29 17:43:32
Java
martin_bleat, 2021-05-29 17:43:32

Java work with BufferedReader what is wrong?

Good afternoon.

I'm doing a tutorial: create a (so far console...) application that registers a participant, asks questions and checks the answers for correctness with the original answers. Questions and correct answers are provided in a text file in the format: question-correct answer-answer options.

What I did:
1) User and question classes, as well as a class with a final form - the history of the passage with all the information.
2) Test class (service), in which I wrote methods for registering, providing a question and accepting an answer, checking

spoiler

public class TestClass {
  private final Deque<Question> questions;
  private int score;
  private final User user;

  public TestClass(List<Question> questions) {
    this.questions = new ArrayDeque(questions);
    this.user = registration();
  }

  private User registration(){
    String name = null;
    String email = null;
    try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in))){
      System.out.println("Name: ");
      name = bufferedReader.readLine();
      System.out.println("E-Mail: ");
      email = bufferedReader.readLine();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return new User(name, email);
  }

  public void startTest(){
    checkQuestions();
    showTestResult(test());
  }

  private boolean checkQuestions(){
    if (questions.isEmpty()){
      throw new EmptyStackException();
    }
    return true;
  }

  private TestResult test(){
    Map<Question, String> answersToQuestions = new HashMap<>();
    Map<String, String> incorrectAnswersToQuestions = new HashMap<>();
    String line = "";
    try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in))) {
      while(!questions.isEmpty()){
        Question currentQuestion = questions.pop();
        System.out.println(currentQuestion.getQuestion());
        System.out.println(currentQuestion.getAnswers());
          line = bufferedReader.readLine();
        answersToQuestions.put(currentQuestion, line);
        if (currentQuestion.getTrueAnswer().equals(line)) {
          score++;
        } else {
          incorrectAnswersToQuestions.put(currentQuestion.getQuestion(), line);
        }
    }
    } catch (IOException ioException) {
      ioException.printStackTrace();
    }
    return new TestResult(answersToQuestions, incorrectAnswersToQuestions, score, user);
  }

  private void showTestResult(TestResult testResult){
    System.out.println("Congratulation! Test finished");
    System.out.println("Result of the test:");
    System.out.println("Date: "+ testResult.getDate());
    System.out.println("User: " + testResult.getUser());
    System.out.println("Score: " + testResult.getScore());
    if (testResult.getIncorrectAnswersToQuestions().isEmpty()){
      System.out.println("All answers is right!");
    } else{
      System.out.println("Incorrect answers: ");
      System.out.println(testResult.getIncorrectAnswersToQuestions().keySet());
    }
  }
}


3) Class for reading a text file of .csv format
spoiler
public class CsvReader {
  private final List<String> lines = new ArrayList<>();

  public CsvReader(String name) {
    try(BufferedReader bufferedReader = new BufferedReader(
        new InputStreamReader(getClass().getClassLoader().getResourceAsStream(name)))) {
      String tempLine = "";
      while((tempLine = bufferedReader.readLine()) != null){
        lines.add(tempLine);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public List<Question> questionReader(){
    List<Question> questions = new ArrayList<>();
    Iterator<String> linesIterator = lines.iterator();
    while(linesIterator.hasNext()){
      String tempLine = linesIterator.next();
      String[] splitLine = tempLine.split(",");
      int questionQuality = splitLine.length-2;
      String[] answers = new String[questionQuality];
      System.arraycopy(splitLine,2, answers,0, questionQuality );
      Question tempQuestion = new Question(splitLine[0], splitLine[1],List.of(answers));
      questions.add(tempQuestion);
    }
    return questions;
  }
}


The problem is the following - I use try with a resource (BufferedReader) in several classes - reading from a resource file, reading from the console, when a question is asked in the try block, there is a while block with console reading ... As a result, an exception is thrown - java.io.IOException : Stream closed.

Judging by the output to the console, when the BufferedReader.readLine method is executed, the actions continue and do not wait until I type something in the console ... Do you need to make a pause?

Full console output:
spoiler
Name: 
q
E-Mail: 
a
1
[3, 4, 2]
Congratulation! Test finished
Result of the test:
Date: 2021-05-29
User: [email protected]5276e6b0
Score: 0
All answers is right!
java.io.IOException: Stream closed
  at java.base/java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:176)
  at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:342)
  at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
  at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
  at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
  at java.base/java.io.InputStreamReader.read(InputStreamReader.java:185)
  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 otus.quester.demo.domain.TestClass.test(TestClass.java:53)
  at otus.quester.demo.domain.TestClass.startTest(TestClass.java:34)
  at otus.quester.demo.DemoApplication.main(DemoApplication.java:14)

Process finished with exit code 0


Because try is used with a resource, I don’t quite understand why it closes before the right moment ... I would like the system to wait until I enter the answer after the question is asked, but this does not happen - the program asks a question and proceeds to the next step without waiting for my answer in the console -> shows result and throws out with exception.
Execution crashes when executing:line = bufferedReader.readLine();


Please help.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
sergey, 2021-05-29
@martin_bleat

the variable is re-read until something is entered:

while (!questions.isEmpty()) {
  String question = questions.pop();
  System.out.println(question);
  String line = null;
  while (line == null || line.isEmpty())
    line = bufferedReader.readLine();
  answer.add(line);
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question