java.lang.Object
java.io.InputStream
xyz.apollosoftware.bibliothiki.compression.utils.PeekableInputStream
All Implemented Interfaces:
Closeable, AutoCloseable

public class PeekableInputStream extends InputStream
A wrapper for InputStream that is able to memoize bytes read after mark(int) to replay them.

This is intended for use in ArchiveInputStream implementations to peek magic headers in streams where markSupported() is false.

As such, this implementation is not designed for peeking large amounts of bytes (i.e., more than ~4 KiB). If working with larger buffers is required, this implementation should be extended to provide an implementation of InputStream.read(byte[], int, int).

  • Constructor Details

  • Method Details

    • ensurePeekable

      public static @NonNull InputStream ensurePeekable(@NonNull InputStream stream)
      If, for the given stream, InputStream.markSupported() returns true, this method is a no-op, returning the provided stream.

      Otherwise, the stream is wrapped with PeekableInputStream.

      Parameters:
      stream - The stream to peek/read from.
      Returns:
      A peekable stream which may be have been wrapped with PeekableInputStream to make it peekable.
    • available

      public int available() throws IOException
      Get an estimate of the number of bytes available in the stream.

      This method nominally preserves the behavior of the InputStream that has been wrapped. However, when the peekable stream isMarked() and then reset() is called, this returns the number of bytes read since mark(int) was called (this should still be treated as an estimate).

      Per the documentation of InputStream.available(), it is never correct to use this to determine the size for buffers for the stream. It is an estimate and many implementations will simply return one or zero to merely indicate whether data is available.

      Overrides:
      available in class InputStream
      Returns:
      The number of available bytes, or zero at the end of the stream.
      Throws:
      IOException - If an I/O error occurs whilst checking for the number of available bytes.
      See Also:
    • markSupported

      public boolean markSupported()
      Overrides:
      markSupported in class InputStream
    • isMarked

      public boolean isMarked()
      Whether the stream is currently marked (i.e., buffering).

      This method returns true when mark(int) has been called and remains true for as long as the stream has not been closed and reset() has not been called.

      Returns:
      True if, and only if, the stream is marked.
    • mark

      public void mark(int limit)
      Overrides:
      mark in class InputStream
    • read

      public int read() throws IOException
      Specified by:
      read in class InputStream
      Throws:
      IOException
    • reset

      public void reset()
      Overrides:
      reset in class InputStream
    • close

      public void close() throws IOException
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Overrides:
      close in class InputStream
      Throws:
      IOException