private long getCachedEndIndex(Path path) throws IOException {
    Long endIndexForFile = endIndexMap.get(path);
    if (endIndexForFile == null) {
      final long bufferSectionSize = 5 * 1024;
      FileSystem fileSystem = path.getFileSystem(conf);
      long endOfFile = fileSystem.getFileStatus(path).getLen();
      if (footerCount == 0) {
        endIndexForFile = endOfFile;
      } else {
        long bufferSectionEnd = endOfFile; // first byte that is not included in the section
        long bufferSectionStart = Math.max(0, bufferSectionEnd - bufferSectionSize);

        // we need 'footer count' lines and one space for EOF
        LineBuffer buffer = new LineBuffer(footerCount + 1);
        FSDataInputStream fis = null;
        try {
          fis = fileSystem.open(path);
          while (bufferSectionEnd > bufferSectionStart) {
            fis.seek(bufferSectionStart);
            long pos = fis.getPos();
            while (pos < bufferSectionEnd) {
              if (fis.readLine() == null) {
                // if there is not enough lines in this section, check the previous
                // section. If this is the beginning section, there are simply not
                // enough lines in the file.
                break;
              }
              pos = fis.getPos();
              buffer.consume(pos, bufferSectionEnd);
            }
            if (buffer.getRemainingLineCount() == 0) {
              // if we consumed all the required line ends, that means the buffer now
              // contains the index of the first byte of the footer.
              break;
            } else {
              bufferSectionEnd = bufferSectionStart;
              bufferSectionStart = Math.max(0, bufferSectionEnd - bufferSectionSize);
            }
          }
          if (buffer.getRemainingLineCount() == 0) {
            // buffer.getFirstLineStart() is the first byte of the footer. So the split
            // must end before this.
            endIndexForFile = buffer.getFirstLineStart() - 1;
          } else {
            // there were not enough lines in the file to consume all footer rows.
            endIndexForFile = Long.MIN_VALUE;
          }
        } finally {
          if (fis != null) {
            fis.close();
          }
        }
      }
      endIndexMap.put(path, endIndexForFile);
    }
    return endIndexForFile;
  }
SkippingInputFormat is a header/footer aware input format. It truncates
splits identified by TextInputFormat. Header and footers are removed
from the splits.

This InputFormat does NOT support Compressed Files!
ql/src/java/org/apache/hadoop/hive/ql/io/SkippingTextInputFormat.java