GatheringByteArrayInputStream extends InputStream { @Override public synchronized long skip(long n) { if (n < 0) { return 0; } long totalSkippedBytes = min(n, remainingBytes); n = totalSkippedBytes; while (n > 0) { if (currentBufferPosition >= currentBuffer.length) { advanceCurrentBuffer(); } int skippedBytes = (int) min(n, currentBuffer.length - currentBufferPosition); n -= skippedBytes; currentBufferPosition += skippedBytes; } remainingBytes -= totalSkippedBytes; return totalSkippedBytes; } GatheringByteArrayInputStream(List<byte[]> buffers, long totalBytes); @Override synchronized int read(byte[] buffer); @Override synchronized int read(); @Override synchronized long skip(long n); @Override synchronized int read(byte[] buffer, int offset, int length); @Override void close();  }
@Test public void testSkip() { byte[] allDataBytes = "Hello, this is http client package, and I am just a test for GatheringByteArrayInputStream".getBytes(UTF_8); int length = allDataBytes.length; try (GatheringByteArrayInputStream in = new GatheringByteArrayInputStream( ImmutableList.of( Arrays.copyOfRange(allDataBytes, 0, length / 3), Arrays.copyOfRange(allDataBytes, length / 3, length / 3 + length / 2), Arrays.copyOfRange(allDataBytes, length / 3 + length / 2, length)), length)) { int skipped = length / 2; int firstPartLength = length / 4; int restPartLength = length - firstPartLength - skipped; byte[] actual = new byte[length - skipped + 10]; assertEquals(in.read(actual, 0, firstPartLength), firstPartLength); assertByteArrayEquals(actual, 0, allDataBytes, 0, firstPartLength); assertEquals(in.skip(skipped), skipped); assertEquals(in.read(actual, firstPartLength, restPartLength + 10), restPartLength); assertByteArrayEquals(actual, firstPartLength, allDataBytes, firstPartLength + skipped, restPartLength); assertEquals(in.skip(10), 0); assertEquals(in.read(), -1); } }