code: private void processFile(InputStream is) throws MPXJException
     {
        int line = 1;
  
        try
        {
           //
           // Test the header and extract the separator. If this is successful,
           // we reset the stream back as far as we can. The design of the
           // BufferedInputStream class means that we can't get back to character
           // zero, so the first record we will read will get "RMHDR" rather than
           // "ERMHDR" in the first field position.
           //
           BufferedInputStream bis = new BufferedInputStream(is);
           byte[] data = new byte[6];
           data[0] = (byte) bis.read();
           bis.mark(1024);
           bis.read(data, 1, 5);
  
           if (!new String(data).equals("ERMHDR"))
           {
              throw new MPXJException(MPXJException.INVALID_FILE);
           }
  
           bis.reset();
  
           InputStreamReader reader = new InputStreamReader(bis, getCharset());
           Tokenizer tk = new ReaderTokenizer(reader);
           tk.setDelimiter('\t');
           List<String> record = new ArrayList<String>();
  
           while (tk.getType() != Tokenizer.TT_EOF)
           {
              readRecord(tk, record);
              if (!record.isEmpty())
              {
                 if (processRecord(record))
                 {
                    break;
                 }
              }
              ++line;
           }
        }
  
        catch (Exception ex)
        {
           throw new MPXJException(MPXJException.READ_ERROR + " (failed at line " + line + ")", ex);
        }
     }
docs: Reads the XER file table and row structure ready for processing.
  
  @param is input stream
  @throws MPXJException