Here’s a simple input stream which will tell you the current position. You should insert this after any buffered input streams if you want an accurate position after a read.
public class CountingInputStream extends PushbackInputStream { private long bytesRead; public CountingInputStream(InputStream is) { super(is); } public CountingInputStream(InputStream is,int len) { super(is,len); } public long getPosition() { return bytesRead; } @Override public void unread(byte[] b, int off, int len) throws IOException { bytesRead -= len; super.unread(b, off, len); } @Override public void unread(int b) throws IOException { bytesRead--; super.unread(b); } @Override public void unread(byte[] b) throws IOException { bytesRead -= b.length; super.unread(b); } @Override public boolean markSupported() { return false; } @Override public synchronized void reset() throws IOException { throw new IOException("Mark not supported"); } @Override public int read() throws IOException { int rd = super.read(); if (rd != -1) { bytesRead++; } return rd; } @Override public int read(byte[] b) throws IOException { int read = super.read(b); if (read != -1) { bytesRead += read; } return read; } @Override public int read(byte[] b, int off, int len) throws IOException { int read = super.read(b, off, len); if (read != -1) { bytesRead += read; } return read; } @Override public long skip(long n) throws IOException { long skipped = super.skip(n); bytesRead += skipped; return skipped; } }