Как избавиться от ошибки недопустимой метки при чтении файла на Java?

#java #bufferedreader

#java #bufferedreader

Вопрос:

Я пытаюсь прочитать файл, но я получаю IOException: ошибка недопустимой метки при запуске кода, даже если он выводит правильный результат непосредственно перед исключением. Если я увеличу значение метки (примерно до 40), это приведет к полному и правильному выводу, но с NullPointerException .

Вот мой код:

      private static void readEventsFile2() throws FileNotFoundException, IOException {
        ArrayList<String> evtList = new ArrayList<>();
        FileReader fr=new FileReader("src/idse/Events.txt"); 
        BufferedReader br = new BufferedReader(fr);
        String a ="";

        try {
            
            while(!(a=br.readLine()).isEmpty()) {
                
                if (isNum(a)){ 
                    numEv = Integer.parseInt(a);
                    System.out.println(numEv);
                } else if(!a.isEmpty()){ 
                    String[] parts = a.split(":");
                    for (String part : parts) {
                        evtList.add(part);
                    }
                }
                br.mark(0);
                a = br.readLine();
                if(a == null || isNum(a)) { 
                    System.out.println(evtList);
                    evtList.clear();
                }
                br.reset();
            }
        } catch (NoSuchElementException | IllegalStateException | NullPointerException e) {
            System.out.println(e);
        }
        
    }   
  

Вывод из приведенного выше кода (строка 149 — br.reset()):

 5
[Logins, 2, Total time online, 1, Emails sent, 1, Orders processed, 1, Pizza’s ordered online, 0.5]
10
Exception in thread "main" java.io.IOException: Mark invalid
    at java.io.BufferedReader.reset(BufferedReader.java:512)
    at idse.IDSE.readEventsFile2(IDSE.java:149)
    at idse.IDSE.main(IDSE.java:188)
  

Формат файла, который я читаю:

 5
Logins:2:Total time online:1:Emails sent:1:Orders processed:1:
Pizza’s ordered online:0.5:
10
Logins:7:Total time online:5:Emails sent:9:Orders processed:15:
Pizza’s ordered online:0.9:Logouts:6
  

Ответ №1:

Параметр int в mark() указывает количество символов / байт, которые будут сохранены в буфере. Если вы прочитаете слишком много данных, которые пересекают размер метки, тогда mark будет invalidated . И при вызове reset() он выдаст это исключение.

Если вы читаете документ для reset() , он говорит, что выдает:

 IOException - If the stream has never been marked,or if the mark has been invalidated
  

Вы можете исправить свой код, увеличив емкость параметра mark .

 br.mark(1000); // 1000 or depending on your buffer.
  

Полный код:

 private static void readEventsFile2() throws FileNotFoundException, IOException {

    ArrayList<String> evtList = new ArrayList<>();
    FileReader fr = new FileReader("C:\Users\Abi.Shaquib\Desktop\overflow.txt");
    BufferedReader br = new BufferedReader(fr);
    String a = "";
    while ((a = br.readLine()) != null) {
        if (isNum(a)) {
            int numEv = Integer.parseInt(a);
            System.out.println(numEv);
        } else if (!a.isEmpty()) {
            String[] parts = a.split(":");
            for (String part : parts) {
                evtList.add(part);
            }
        }
        br.mark(1000);
        a = br.readLine();
        if (a == null || isNum(a)) {
            System.out.println(evtList);
            evtList.clear();
        }
        br.reset();
    }
}
  

Вывод:

 5
[Logins, 2, Total time online, 1, Emails sent, 1, Orders processed, 1, Pizza's ordered online, 0.5]
10
[Logins, 7, Total time online, 5, Emails sent, 9, Orders processed, 15, Pizza's ordered online, 0.9, Logouts, 6]
  

Комментарии:

1. Я увеличил емкость параметра mark, но затем я начинаю получать исключение NullPointerException

2. while ((a = br.readLine()) != null) { используйте это в цикле while. isEmpty не проверяет наличие null

3. Какое значение int вы даете? Сколько времени занимает ваш ввод??

4. Формат, который я вставил внизу, — это то, что находится в файле. Я перепробовал много значений для метки от 0 до тысяч. Ни один из них не работает, я либо получаю недопустимую метку, либо исключение NullPointerException.

5. Спасибо, я попробовал с кодом, который вы опубликовали, и теперь он работает! Я даже пробовал использовать значения больше 1000 раньше, но в тот раз это не сработало.