I am trying to parse InputEvents of an Android device.Background:For an android device we have a utility getevent which gives all the touch events that are sent to a device. getevent -l gives all the input events to the device. Every event has 3 fields - EVENT_TYPE, EVENT_CODE and VALUE.EVENT_TYPE can be of following types - EV_KEY, EV_ABS and EV_SYN.In turn, each EVENT_TYPE can have different EVENT_CODES. For e.g.EV_KEY --> BTN_TOUCHEV_ABS --> ABS_MT_TOUCH_MAJOR, ABS_MT_TRACKING_ID, ABS_MT_POSITION_X, ABS_MT_POSITION_Y and EV_SYN --> SYN_MT_REPORT, SYN_REPORTAnd every EVENT_CODE can have a VALUE.Every event is separated by a SYN_REPORT.Each event can itself be a multi touch event be separated by a SYN_MT_REPORT.Every touch starts with a EV_KEY - BTN_TOUCH - DOWN and ends with a EV_KEY - BTN_TOUCH - UP combination. (There are event separators after EV_KEY - BTN_TOUCH - UP viz. SYN_MT_REPORT and SYN_REPORT, but they are not important.More description: Event Types and Multi Touch eventsEV_KEY       BTN_TOUCH            DOWN     <--------------EV_ABS       ABS_MT_TOUCH_MAJOR   00000011               |EV_ABS       ABS_MT_TRACKING_ID   00000000               |EV_ABS       ABS_MT_POSITION_X    0000011c               |---First event,EV_ABS       ABS_MT_POSITION_Y    000001f4               |   with DOWN and onlyEV_SYN       SYN_MT_REPORT        00000000               |   1 finger touched.EV_SYN       SYN_REPORT           00000000 <--------------EV_ABS       ABS_MT_TOUCH_MAJOR   00000011 <--------------EV_ABS       ABS_MT_TRACKING_ID   00000000 <-------      | EV_ABS       ABS_MT_POSITION_X    0000011c        |      | EV_ABS       ABS_MT_POSITION_Y    000001f4   Finger 1    | EV_SYN       SYN_MT_REPORT        00000000 <-------      | EV_ABS       ABS_MT_TOUCH_MAJOR   00000013               |---Second eventEV_ABS       ABS_MT_TRACKING_ID   00000001 <-------      |   with 2 mutitouch eventsEV_ABS       ABS_MT_POSITION_X    00000076        |      | EV_ABS       ABS_MT_POSITION_Y    0000026e   Finger 2    | EV_SYN       SYN_MT_REPORT        00000000 <-------      |         EV_SYN       SYN_REPORT           00000000 <--------------EV_ABS       ABS_MT_TOUCH_MAJOR   00000011 <--------------  EV_ABS       ABS_MT_TRACKING_ID   00000000 <-------      |  EV_ABS       ABS_MT_POSITION_X    00000190        |      |  EV_ABS       ABS_MT_POSITION_Y    0000035d   Finger 1    |  EV_SYN       SYN_MT_REPORT        00000000 <-------      |  EV_ABS       ABS_MT_TOUCH_MAJOR   00000013               |  EV_ABS       ABS_MT_TRACKING_ID   00000001 <-------      |   EV_ABS       ABS_MT_POSITION_X    000000f8        |      |   EV_ABS       ABS_MT_POSITION_Y    000003cf   Finger 2    |---Third eventEV_SYN       SYN_MT_REPORT        00000000 <-------      |   with 3 mulittouch events  EV_ABS       ABS_MT_TOUCH_MAJOR   00000015               |EV_ABS       ABS_MT_TRACKING_ID   00000002 <-------      |  EV_ABS       ABS_MT_POSITION_X    00000251        |      |  EV_ABS       ABS_MT_POSITION_Y    00000310   Finger 3    |  EV_SYN       SYN_MT_REPORT        00000000 <-------      |          EV_SYN       SYN_REPORT           00000000 <--------------  EV_KEY       BTN_TOUCH            UP       <--------------  EV_SYN       SYN_MT_REPORT        00000000               |---Final Event,  EV_SYN       SYN_REPORT           00000000 <--------------   only 1 fingerAn example of actual input is:EV_KEY       BTN_TOUCH            DOWN                EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000011c            EV_ABS       ABS_MT_POSITION_Y    000001f4            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000011c            EV_ABS       ABS_MT_POSITION_Y    000001f4            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    00000076            EV_ABS       ABS_MT_POSITION_Y    0000026e            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000011c            EV_ABS       ABS_MT_POSITION_Y    000001f4            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    00000076            EV_ABS       ABS_MT_POSITION_Y    0000026e            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    000001cd            EV_ABS       ABS_MT_POSITION_Y    000001a3            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000011c            EV_ABS       ABS_MT_POSITION_Y    000001f4            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    00000076            EV_ABS       ABS_MT_POSITION_Y    0000026e            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    000001cd            EV_ABS       ABS_MT_POSITION_Y    000001a3            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000011c            EV_ABS       ABS_MT_POSITION_Y    000001f4            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    00000076            EV_ABS       ABS_MT_POSITION_Y    0000026e            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    000001cd            EV_ABS       ABS_MT_POSITION_Y    000001a3            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000011c            EV_ABS       ABS_MT_POSITION_Y    000001f4            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    00000076            EV_ABS       ABS_MT_POSITION_Y    0000026e            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    000001cd            EV_ABS       ABS_MT_POSITION_Y    000001a3            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000011c            EV_ABS       ABS_MT_POSITION_Y    000001f4            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    00000076            EV_ABS       ABS_MT_POSITION_Y    0000026e            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    000001cd            EV_ABS       ABS_MT_POSITION_Y    000001a3            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000011c            EV_ABS       ABS_MT_POSITION_Y    000001f4            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    00000076            EV_ABS       ABS_MT_POSITION_Y    0000026e            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    000001cd            EV_ABS       ABS_MT_POSITION_Y    000001a3            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000011c            EV_ABS       ABS_MT_POSITION_Y    000001f4            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    00000076            EV_ABS       ABS_MT_POSITION_Y    0000026e            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    000001cd            EV_ABS       ABS_MT_POSITION_Y    000001a3            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000011c            EV_ABS       ABS_MT_POSITION_Y    000001f4            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    00000076            EV_ABS       ABS_MT_POSITION_Y    0000026e            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    000001cd            EV_ABS       ABS_MT_POSITION_Y    000001a3            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000014b            EV_ABS       ABS_MT_POSITION_Y    0000026e            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    000000b7            EV_ABS       ABS_MT_POSITION_Y    000002ef            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    00000209            EV_ABS       ABS_MT_POSITION_Y    00000225            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000015f            EV_ABS       ABS_MT_POSITION_Y    000002a1            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    000000c7            EV_ABS       ABS_MT_POSITION_Y    00000319            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    0000021e            EV_ABS       ABS_MT_POSITION_Y    00000258            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    00000167            EV_ABS       ABS_MT_POSITION_Y    000002cc            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    000000d4            EV_ABS       ABS_MT_POSITION_Y    00000339            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    00000228            EV_ABS       ABS_MT_POSITION_Y    0000027d            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000016f            EV_ABS       ABS_MT_POSITION_Y    000002ed            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    000000dd            EV_ABS       ABS_MT_POSITION_Y    0000035e            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    00000231            EV_ABS       ABS_MT_POSITION_Y    000002a1            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    00000178            EV_ABS       ABS_MT_POSITION_Y    0000030f            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    000000e4            EV_ABS       ABS_MT_POSITION_Y    0000037d            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    0000023a            EV_ABS       ABS_MT_POSITION_Y    000002c2            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    00000182            EV_ABS       ABS_MT_POSITION_Y    00000329            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    000000eb            EV_ABS       ABS_MT_POSITION_Y    0000039b            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    00000242            EV_ABS       ABS_MT_POSITION_Y    000002de            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000018a            EV_ABS       ABS_MT_POSITION_Y    00000343            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    000000ef            EV_ABS       ABS_MT_POSITION_Y    000003b3            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    00000247            EV_ABS       ABS_MT_POSITION_Y    000002f6            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000018e            EV_ABS       ABS_MT_POSITION_Y    00000354            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    000000f3            EV_ABS       ABS_MT_POSITION_Y    000003c2            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    0000024d            EV_ABS       ABS_MT_POSITION_Y    00000306            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    0000018f            EV_ABS       ABS_MT_POSITION_Y    0000035c            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    000000f5            EV_ABS       ABS_MT_POSITION_Y    000003cb            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    0000024f            EV_ABS       ABS_MT_POSITION_Y    0000030e            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            EV_ABS       ABS_MT_TRACKING_ID   00000000            EV_ABS       ABS_MT_POSITION_X    00000190            EV_ABS       ABS_MT_POSITION_Y    0000035d            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            EV_ABS       ABS_MT_TRACKING_ID   00000001            EV_ABS       ABS_MT_POSITION_X    000000f8            EV_ABS       ABS_MT_POSITION_Y    000003cf            EV_SYN       SYN_MT_REPORT        00000000            EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            EV_ABS       ABS_MT_TRACKING_ID   00000002            EV_ABS       ABS_MT_POSITION_X    00000251            EV_ABS       ABS_MT_POSITION_Y    00000310            EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000            EV_KEY       BTN_TOUCH            UP                  EV_SYN       SYN_MT_REPORT        00000000            EV_SYN       SYN_REPORT           00000000This is how I am trying to parse it:package com.xolo;import java.io.*;import java.util.ArrayList;import java.util.List;public class Main {    public Main() {    }    public void readFile() {        File file = new File(....../output2.txt);        List<Event> listOfEvents = null;        try {            BufferedReader is = new BufferedReader(new InputStreamReader(new FileInputStream(file)));            listOfEvents = createEvents(is);        } catch (FileNotFoundException e) {            e.printStackTrace();        }        if (listOfEvents == null) {            return;        }        for (Event event : listOfEvents) {            System.out.println(event.toString());        }    }    private List<Event> createEvents(BufferedReader is) {        List<Event> listOfEvents = new ArrayList<>();        Event event = null;        String[] tokens;        try {            while (true) {                tokens = is.readLine().split(\\s+);                if (tokens[1].equalsIgnoreCase(BTN_TOUCH)) {                    if (tokens[2].equalsIgnoreCase(DOWN)) {                        event = new Event();                        continue;                    } else if (tokens[2].equalsIgnoreCase(UP)) {                        tokens = is.readLine().split(\\s+);                        if (tokens[1].equalsIgnoreCase(SYN_MT_REPORT)) {                            tokens = is.readLine().split(\\s+);                            if (tokens[1].equalsIgnoreCase(SYN_REPORT)) {                                return listOfEvents;                            } else {                                throw new IllegalArgumentException();                            }                        } else {                            throw new IllegalArgumentException();                        }                    }                } else if (tokens[1].equalsIgnoreCase(ABS_MT_TOUCH_MAJOR)) {                    event.mtEvents.add(createMTEvent(is));                } else if (tokens[1].equalsIgnoreCase(SYN_REPORT)) {                    if (event == null) {                        throw new IllegalArgumentException();                    }                    listOfEvents.add(event);                    event = new Event();                }            }        } catch (IOException e) {            e.printStackTrace();        }        return null;    }    private MTEvent createMTEvent(BufferedReader is) {        String[] tokens;        try {            tokens = is.readLine().split(\\s+);            if (!tokens[1].equalsIgnoreCase(ABS_MT_TRACKING_ID)) {                throw new IllegalArgumentException();            }            int id = Integer.valueOf(tokens[2]);            tokens = is.readLine().split(\\s+);            if (!tokens[1].equalsIgnoreCase(ABS_MT_POSITION_X)) {                throw new IllegalArgumentException();            }            int x = Integer.parseInt(tokens[2], 16);            tokens = is.readLine().split(\\s+);            if (!tokens[1].equalsIgnoreCase(ABS_MT_POSITION_Y)) {                throw new IllegalArgumentException();            }            int y = Integer.parseInt(tokens[2], 16);            tokens = is.readLine().split(\\s+);            if (!tokens[1].equalsIgnoreCase(SYN_MT_REPORT)) {                throw new IllegalArgumentException();            }            return new MTEvent(id, x, y);        } catch (IOException e) {            e.printStackTrace();        } catch (IllegalArgumentException e) {        }        return null;    }    public static void main(String[] args) {        Main mn = new Main();        mn.readFile();    }    private class MTEvent {        int trackingID;        int x;        int y;        public MTEvent(int id, int x, int y) {            this.trackingID = id;            this.x = x;            this.y = y;        }        @Override        public String toString() {            return ID:  + trackingID + , x:  + x + , y:  + y;        }    }    private class Event {        List<MTEvent> mtEvents;        Event() {            mtEvents = new ArrayList<>();        }        @Override        public String toString() {            StringBuilder stringBuilder = new StringBuilder();            stringBuilder.append(Event: \n);            for (MTEvent mtEvent : mtEvents) {                stringBuilder.append(mtEvent.toString()).append(\n);            }            return stringBuilder.toString();        }    }}I tried to separate the individual event and MultiTouch event into separate methods but I don't think I have done it right.There are a number of things that I want to correct:The parsing logic itself.The Exceptions thrown (any different way to do it?)The splitting of input on space characters (any better way to do it?).
Parsing a file for an Android device
java;parsing;android
NamingThe first point i'd like to raise is the naming of your class i.e. Main. This isn't very descriptive of what your intention is. I'd expect a class like AndroidTouchInputEventsReader that contains a method such as  List<Event> parseAndroidTouchEvents(BufferedReader);.  Try to think in terms of another programmer using the code, and attempt to make it clear how to use your methods.class Main -> lets rename this AndroidTouchInputEventsReaderreadFile() -> lets change this to List<Event> parseAndroidTouchEvents(BufferedReader)Then, external to this class we can handle creation of a BufferedReader which could come from a file or in fact any InputStream. DataThe classes Event being private to the Main class will hide the implementation to the Users. Currently that's OK as you're only printing the Events to the console, but if you think of your class as a way of getting InputEvents in a different part of your program this won't work. In order for the next step to work, I would enable an MTEvent to be updated using setter methods, so I would add setParsingFirstly, I agree with you splitting your lines on spaces. This certainly fits the file format. I would like to have seen you decouple the reading of the file to the parsing of the lines. A standard way of dealing with parsing a sequence of things in a certain order is a Finite State Machine. A state machine stores a current state, and has a nextState method, that will verify the input and move to the next state. An easy way of doing this in Java is using an enum. We have the statescurrent state      | action                                     | next stateINITIAL            | t[1] = BTN_TOUCH &  t[2] =DOWN             | BT_TOUCH-down   BTN_TOUCH-down     | t[1] = ABS_MT_TOUCH_MAJOR                  | ABS_MT_TOUCH_MAJORABS_MT_TOUCH_MAJOR | read t[1] trackingid, update MTEvent       | ABS_MT_TRACKING_ID ABS_MT_TRACKING_ID | read t[1] =x, update MTEvent               | ABS_MT_POSITION_X    ABS_MT_POSITION_X  |read t[1] =y, update MTEvent                | ABS_MT_POSITION_Y   ABS_MT_POSITION_Y  | t[1] = (mt_report)                         | SYN_MT_REPORTSYN_MT_REPORT      | save MTEvent to event                    | if t[1] =(touchMajor)                      | ABS_MT_TOUCH_MAJOR                   | if t[1] = (synReport)                      | SYN_REPORTSYN_REPORT         | add the event to list.                    | t[1]=(touchMajor)                          | ABS_MT_TOUCH_MAJOR                   | if t[1]=(BTN_TOUCH-up)                     | BTN_TOUCH-up                   | if (EOF)                                   | ENDBTN_TOUCH-UP       | token[1]= SYN_MT_REPORT                    | SYN_MT_REPORTAt each state, you check whether the input line is valid, and update the Event with data. You know at SYN_MT_REPORT you add the MTEvent to the Event's List and at SYN_REPORT you have read the whole event, so you can add the event to the event list. If the line isn't valid, have it throw a parseException that your main read loop can catch.Based on the input, you also choose the next state, So, when you're in the SYN_MT_REPORT state,  when you next call parseLine, the next command could be a ABS_MT_TOUCH_MAJOR or a SYN_REPORT, so in the nextAction method, the line read will decide between each.If you read the SYN_REPORT state, you know that you have a complete event, and to add the list of MTEvent in to the current EventIf you read the ABS_MT_TOUCH_MAJOR you know the next state will  be ABS_MT_TRACKING_ID for another multi-touch event.This is how I would create the enumprivate static enum TouchEventState {    INITIAL{        @Override        public TouchEventState processLine(String line, int currentLine, Event currentEvent, List<Event> ret) throws ParseException {             String[] tokens = tokenize(line);            if (validateLine(tokens)){                return BTN_TOUCH_DOWN;            } else {                throw new ParseException(line, currentLine);            }        }        boolean validateLine(String[] tokens){            return tokens.length == COLS                && tokens[1].equalsIgnoreCase(BTN_TOUCH)                 &&  tokens[2].equalsIgnoreCase(DOWN);        }    },    BTN_TOUCH_DOWN{        @Override        public TouchEventState processLine(String line,int currentLine, Event currentEvent, List<Event> ret) {            String[] tokens = tokenize(line);            if (validateLine(tokens){                return ABS_MT_TOUCH_MAJOR;            } else {               throw new ParseException(line, currentLine);            }        }         boolean validateLine(String[] tokens){            return tokens.length == COLS             && tokens[1].equalsIgnoreCase(ABS_MT_TOUCH_MAJOR);        }    },    ABS_MT_TOUCH_MAJOR    {        TouchEventState processLine(String line, int currentLine,                Event currentEvent,MTEvent currentMtEvent, List<Event> ret) throws ParseException {            //if valid input (you've read ,EV_ABS       ABS_MT_TRACKING_ID   00000000) do             //currentMtEvent.setTrackingId(000000);        }    },    ABS_MT_TRACKING_ID   {        TouchEventState processLine(String line, int currentLine,                Event currentEvent,MTEvent currentMtEvent, List<Event> ret) throws ParseException {            //if valid input, currentMtEvent.setPosX(tokens[1]);        }    },    ABS_MT_POSITION_X    {        TouchEventState processLine(String line, int currentLine,                Event currentEvent,MTEvent currentMtEvent, List<Event> ret) throws ParseException {            //if valid input, currentMtEvent.setPosY(tokens[1]);            //return ABS_MT_POSITION_Y        }    },    ABS_MT_POSITION_Y        {    // Read this->  EV_SYN       SYN_MT_REPORT        00000000,     // currentEvent.addMtEvent(currentMtEvent);    // return SYN_MT_REPORT    },    SYN_MT_REPORT       {        TouchEventState processLine(String line, int currentLine,                Event currentEvent,MTEvent currentMtEvent, List<Event> ret) throws ParseException {            //if valid input = SYN_REPORT   ,             //ret.addEvent(currentEvent);        }    },    SYN_REPORT           {        TouchEventState processLine(String line, int currentLine,                Event currentEvent,MTEvent currentMtEvent, List<Event> ret) throws ParseException {            //if input = ABS_MT_TOUCH_MAJOR -> currentEvent = new Event, currentMtEvent = new currentMtEvent(), return ABS_MT_TOUCH_MAJOR             //if EOF return FINISH        }    }; String[] tokenize(String line) {     return line.split(\\+s); }so your processing loop becomeswhile((currentLine = reader.readLine()) != null){    try{        state = state.processLine(currentLine, lineNumber, currentEvent, ret);        ++lineNumber;    } catch (ParseException pse) {        // error with the input - out of sync.        throw pse;    }}return ret;ConclusionWhen creating a new class I would encourage you to think about how it will be used in the rest of the System, or by another User. This leads to better naming and easier to understand code.When parsing, a sequence, I would always use a loop to read each line of the file, then a state machine to decide what to do with that line. 