Miztory
Miztory

Reputation: 198

How to get rid of Invalid Mark error while reading a file in Java?

I am trying to read a file but I am getting IOException: Invalid mark error when I run the code even though it outputs the correct result just before the exception. If I increase the value of the mark (to around 40) it produces the complete and correct output but with NullPointerException.

Here's my code:

     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);
        }
        
    }   

Output from the above code (line 149 is 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)

Format of the file I am reading:

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

Upvotes: 2

Views: 2429

Answers (1)

sn-
sn-

Reputation: 488

The int parameter in mark() indicates the number of characters/bytes to be stored in the buffer. If you read too much data that crosses the size of the mark, then the mark will be invalidated. And upon calling reset(), it will give that exception.

If you read the document for reset(), it says it throws:

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

You can fix your code by increasing the capacity of the mark parameter.

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

Complete Code:

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();
    }
}

Output:

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]

Upvotes: 3

Related Questions