TailStream extends FilterInputStream { @Override public long skip(long n) throws IOException { int bufSize = (int) Math.min(n, SKIP_SIZE); byte[] buf = new byte[bufSize]; long bytesSkipped = 0; int bytesRead = 0; while(bytesSkipped < n && bytesRead != -1) { int len = (int) Math.min(bufSize, n - bytesSkipped); bytesRead = read(buf, 0, len); if(bytesRead != -1) { bytesSkipped += bytesRead; } } return (bytesRead < 0 && bytesSkipped == 0) ? -1 : bytesSkipped; } TailStream(InputStream in, int size); @Override int read(); @Override int read(byte[] buf); @Override int read(byte[] buf, int ofs, int length); @Override long skip(long n); @Override void mark(int limit); @Override void reset(); byte[] getTail();  }
@Test public void testSkip() throws IOException { final int tailSize = 128; final int count = 1024; final int skipCount = 512; TailStream stream = new TailStream(generateStream(0, count), tailSize); assertEquals("Wrong skip result", skipCount, stream.skip(skipCount)); assertEquals("Wrong buffer", generateText(skipCount - tailSize, tailSize), new String(stream.getTail(), UTF_8)); stream.close(); }
@Test public void testSkipReadEnd() throws IOException { final int count = 128; TailStream stream = new TailStream(generateStream(0, count), 2 * count); readStream(stream); assertEquals("Wrong result", -1, stream.skip(1)); }