MemorizingBufferedInputStream extends FilterInputStream { @Override public synchronized String toString() { StringBuilder result; if (isClosed) { result = new StringBuilder(64); } else { result = new StringBuilder((availableToRead() + availableInMemory()) * 2 + 128); } result.append("MemorizingBufferedInputStream{\n"); if (isClosed) { result.append("closed=true\n"); } else if (charset == null) { final BaseEncoding base64 = BaseEncoding.base64(); result.append("readBytes=\"").append(base64.encode(getReadBytesFromBuffer())).append("\",\n"); result.append("unreadBytes=\"").append(base64.encode(getUnreadBytesFromBuffer())).append("\"\n"); } else { try { result.append("readStr=\"").append( charset.newDecoder().onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE).replaceWith("?") .decode(ByteBuffer.wrap(getReadBytesFromBuffer()))).append("\",\n"); result.append("unreadStr=\"").append( charset.newDecoder().onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE).replaceWith("?") .decode(ByteBuffer.wrap(getUnreadBytesFromBuffer()))).append("\"\n"); } catch (CharacterCodingException ex) { throw new UncheckedIOException(ex); } } result.append("memIdx=").append(this.memIdx).append("\"\n"); result.append("startIdx=").append(this.startIdx).append("\"\n"); result.append("endIdx=").append(this.endIdx).append("\"\n"); result.append('}'); return result.toString(); } MemorizingBufferedInputStream(final InputStream in);  MemorizingBufferedInputStream(final InputStream in, final int size);  MemorizingBufferedInputStream(final InputStream in, final Charset charset);  MemorizingBufferedInputStream(final InputStream in, final Charset charset, final int size);  MemorizingBufferedInputStream(final InputStream in,
            final int size, final int readSize,
            final SizedRecyclingSupplier<byte[]> bufferProvider,
            @Nullable final Charset charset); @Override @DischargesObligation synchronized void close(); synchronized byte[] getReadBytesFromBuffer(); synchronized byte[] getUnreadBytesFromBuffer(); @Override synchronized int read(final byte[] b, final int off, final int len); @Override synchronized int read(); @Override synchronized int available(); @Override synchronized String toString(); synchronized long getReadBytes(); @Override synchronized long skip(final long n); @Override boolean markSupported(); @Override synchronized void reset(); @Override synchronized void mark(final int readlimit);  }
@Test public void testStreamBuffering() throws IOException { test(TSTR, 8, true); for (int i = 0; i < 100; i++) { ThreadLocalRandom rnd = ThreadLocalRandom.current(); int nrChars = rnd.nextInt(0, 100000); int bufferSize = rnd.nextInt(2, 100000); StringBuilder sb = generateTestStr(nrChars); test(sb.toString(), bufferSize, true); testBuff(sb, 8192); testBuff(sb, 32); } }