Задать вопрос
@martin_bleat

Java работа с BufferedReader в чем ошибка?

Добрый день.

Выполняю учебное задание: создать (пока консольное...) приложение, регистрирующее участника, задающее вопросы и проверяющее ответы на корректность с исходными ответами. Вопросы и правильные ответы предоставлены в текстовом файле в формате: вопрос-правильный ответ - варианты ответов.

Что я сделал:
1) Классы пользователя и вопроса, а также класс с формуляром итоговым - история прохождения со всей инфой.
2) Тестовый класс (сервис), в котором я прописал методы по регистрации, предоставлению вопроса и принятию ответа, проверки
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) Класс для чтения текстового файла формата .csv
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;
  }
}


Проблема следующая - у меня в нескольких классах используется try с ресурсом (BufferedReader) - чтение из файла ресурса, чтение из консоли, при задаче вопроса в блоке try присутствует блок while с чтением консоли... В результате вылетает исключение - java.io.IOException: Stream closed.

Судя по выводу в консоль при выполнении метода BufferedReader.readLine действия продолжаются и не ждут, пока я наберу что-либо в консоли... Паузу оформлять не нужно никакую?

Полный вывод консоли:
spoiler
Name: 
q
E-Mail: 
a
1
[3, 4, 2]
Congratulation! Test finished
Result of the test:
Date: 2021-05-29
User: quester.demo.domain.User@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


Т.к. используется try с ресурсом не очень понимаю почему он закрывается до нужного момента... Хотелось бы, чтобы после заданного вопроса система ждала, пока я введу ответ, но этого не происходит - программа задает вопрос и переходит к следующему шагу не дожидаясь моего ответа в консоли -> показывает результат и выкидывает с эксепшеном.
Эксепшен вылетает при выполнении: line = bufferedReader.readLine();


Прошу помощи.
  • Вопрос задан
  • 307 просмотров
Подписаться 1 Простой 4 комментария
Решения вопроса 1
переменная пере-считывается до тех пор пока что-нибудь не будет введено:

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);
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы