TailStream extends FilterInputStream { public byte[] getTail() { int size = (int) Math.min(tailSize, bytesRead); byte[] result = new byte[size]; System.arraycopy(tailBuffer, currentIndex, result, 0, size - currentIndex); System.arraycopy(tailBuffer, 0, result, size - currentIndex, currentIndex); return result; } 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 testTailBeforeRead() throws IOException { TailStream stream = new TailStream(generateStream(0, 100), 50); assertEquals("Wrong buffer length", 0, stream.getTail().length); stream.close(); }
@Test public void testTailBufferPartlyRead() throws IOException { final int count = 64; TailStream stream = new TailStream(generateStream(0, count), 2 * count); byte[] data = readStream(stream); assertTrue("Wrong content", Arrays.equals(data, stream.getTail())); stream.close(); }
@Test public void testTailSingleByteReads() throws IOException { final int count = 128; TailStream stream = new TailStream(generateStream(0, 2 * count), count); readStream(stream); assertEquals("Wrong buffer", generateText(count, count), new String( stream.getTail(), UTF_8)); }