Class BoundedInputStream

  • All Implemented Interfaces:
    java.io.Closeable, java.lang.AutoCloseable

    public class BoundedInputStream
    extends ProxyInputStream
    Reads bytes up to a maximum count and stops once reached.

    To build an instance: Use the builder() to access all features.

    By default, a BoundedInputStream is unbound; so make sure to call BoundedInputStream.AbstractBuilder.setMaxCount(long).

    You can find out how many bytes this stream has seen so far by calling getCount(). This value reflects bytes read and skipped.

    Using a ServletInputStream

    A ServletInputStream can block if you try to read content that isn't there because it doesn't know whether the content hasn't arrived yet or whether the content has finished. Initialize an BoundedInputStream with the Content-Length sent in the ServletInputStream's header, this stop it from blocking, providing it's been sent with a correct content length in the first place.

    Using NIO

    
     BoundedInputStream s = BoundedInputStream.builder()
       .setPath(Paths.get("MyFile.xml"))
       .setMaxCount(1024)
       .setPropagateClose(false)
       .get();
     
     

    Using IO

    
     BoundedInputStream s = BoundedInputStream.builder()
       .setFile(new File("MyFile.xml"))
       .setMaxCount(1024)
       .setPropagateClose(false)
       .get();
     
     

    Counting Bytes

    You can set the running count when building, which is most useful when starting from another stream:

    
     InputStream in = ...;
     BoundedInputStream s = BoundedInputStream.builder()
       .setInputStream(in)
       .setCount(12)
       .setMaxCount(1024)
       .setPropagateClose(false)
       .get();
     
     

    Listening for the maximum count reached

    
     BoundedInputStream s = BoundedInputStream.builder()
       .setPath(Paths.get("MyFile.xml"))
       .setMaxCount(1024)
       .setOnMaxCount((max, count) -> System.out.printf("Maximum count %,d reached with a last read count of %,d%n", max, count))
       .get();
     
     
    Since:
    2.0
    See Also:
    BoundedInputStream.Builder
    • Field Detail

      • count

        private long count
        The current count of bytes counted.
      • mark

        private long mark
        The current mark.
      • maxCount

        private final long maxCount
        The maximum count of bytes to read.
      • onMaxCount

        private final IOBiConsumer<java.lang.Long,​java.lang.Long> onMaxCount
      • propagateClose

        private boolean propagateClose
        Flag if close should be propagated. TODO Make final in 3.0.
    • Constructor Detail

      • BoundedInputStream

        private BoundedInputStream​(BoundedInputStream.Builder builder)
                            throws java.io.IOException
        Throws:
        java.io.IOException
      • BoundedInputStream

        @Deprecated
        public BoundedInputStream​(java.io.InputStream in)
        Deprecated.
        Constructs a new BoundedInputStream that wraps the given input stream and is unbounded.

        To build an instance: Use the builder() to access all features.

        Parameters:
        in - The wrapped input stream.
      • BoundedInputStream

        @Deprecated
        public BoundedInputStream​(java.io.InputStream inputStream,
                                  long maxCount)
        Deprecated.
        Constructs a new BoundedInputStream that wraps the given input stream and limits it to a certain size.
        Parameters:
        inputStream - The wrapped input stream.
        maxCount - The maximum number of bytes to return, negative means unbound.
    • Method Detail

      • afterRead

        protected void afterRead​(int n)
                          throws java.io.IOException
        Adds the number of read bytes to the count.
        Overrides:
        afterRead in class ProxyInputStream
        Parameters:
        n - number of bytes read, or -1 if no more bytes are available.
        Throws:
        java.io.IOException - Not thrown here but subclasses may throw.
        Since:
        2.0
      • available

        public int available()
                      throws java.io.IOException
        Description copied from class: ProxyInputStream
        Invokes the delegate's InputStream.available() method.
        Overrides:
        available in class ProxyInputStream
        Returns:
        the number of available bytes, 0 if the stream is closed.
        Throws:
        java.io.IOException - if an I/O error occurs.
      • close

        public void close()
                   throws java.io.IOException
        Invokes the delegate's InputStream.close() method if isPropagateClose() is true.
        Specified by:
        close in interface java.lang.AutoCloseable
        Specified by:
        close in interface java.io.Closeable
        Overrides:
        close in class ProxyInputStream
        Throws:
        java.io.IOException - if an I/O error occurs.
      • getCount

        public long getCount()
        Gets the count of bytes read.
        Returns:
        The count of bytes read.
        Since:
        2.12.0
      • getMaxCount

        public long getMaxCount()
        Gets the maximum number of bytes to read.
        Returns:
        The maximum number of bytes to read, or -1 if unbounded.
        Since:
        2.16.0
      • getMaxLength

        @Deprecated
        public long getMaxLength()
        Deprecated.
        Gets the maximum count of bytes to read.
        Returns:
        The maximum count of bytes to read.
        Since:
        2.12.0
      • getRemaining

        public long getRemaining()
        Gets the number of bytes remaining to read before the maximum is reached.

        This method does not report the bytes available in the underlying stream; it only reflects the remaining allowance imposed by this BoundedInputStream.

        Returns:
        The number of bytes remaining to read before the maximum is reached, or Long.MAX_VALUE if no bound is set.
        Since:
        2.16.0
      • isMaxCount

        private boolean isMaxCount()
      • isPropagateClose

        public boolean isPropagateClose()
        Tests whether the close() method should propagate to the underling InputStream.
        Returns:
        true if calling close() propagates to the close() method of the underlying stream or false if it does not.
      • mark

        public void mark​(int readLimit)
        Invokes the delegate's InputStream.mark(int) method.
        Overrides:
        mark in class ProxyInputStream
        Parameters:
        readLimit - read ahead limit.
      • onMaxLength

        protected void onMaxLength​(long max,
                                   long count)
                            throws java.io.IOException
        A caller has caused a request that would cross the maxLength boundary.

        Delegates to the consumer set in BoundedInputStream.AbstractBuilder.setOnMaxCount(IOBiConsumer).

        Parameters:
        max - The maximum count of bytes to read.
        count - The count of bytes read.
        Throws:
        java.io.IOException - Subclasses may throw.
        Since:
        2.12.0
      • read

        public int read()
                 throws java.io.IOException
        Invokes the delegate's InputStream.read() method if the current position is less than the limit.
        Overrides:
        read in class ProxyInputStream
        Returns:
        the byte read or -1 if the end of stream or the limit has been reached.
        Throws:
        java.io.IOException - if an I/O error occurs.
      • read

        public int read​(byte[] b)
                 throws java.io.IOException
        Invokes the delegate's InputStream.read(byte[]) method.
        Overrides:
        read in class ProxyInputStream
        Parameters:
        b - the buffer to read the bytes into.
        Returns:
        the number of bytes read or -1 if the end of stream or the limit has been reached.
        Throws:
        java.io.IOException - if an I/O error occurs.
      • read

        public int read​(byte[] b,
                        int off,
                        int len)
                 throws java.io.IOException
        Invokes the delegate's InputStream.read(byte[], int, int) method.
        Overrides:
        read in class ProxyInputStream
        Parameters:
        b - the buffer to read the bytes into.
        off - The start offset.
        len - The number of bytes to read.
        Returns:
        the number of bytes read or -1 if the end of stream or the limit has been reached.
        Throws:
        java.io.IOException - if an I/O error occurs.
      • reset

        public void reset()
                   throws java.io.IOException
        Invokes the delegate's InputStream.reset() method.
        Overrides:
        reset in class ProxyInputStream
        Throws:
        java.io.IOException - if an I/O error occurs.
      • setPropagateClose

        @Deprecated
        public void setPropagateClose​(boolean propagateClose)
        Sets whether the close() method should propagate to the underling InputStream.
        Parameters:
        propagateClose - true if calling close() propagates to the close() method of the underlying stream or false if it does not.
      • skip

        public long skip​(long n)
                  throws java.io.IOException
        Invokes the delegate's InputStream.skip(long) method.
        Overrides:
        skip in class ProxyInputStream
        Parameters:
        n - the number of bytes to skip.
        Returns:
        the actual number of bytes skipped.
        Throws:
        java.io.IOException - if an I/O error occurs.
      • toReadLen

        private long toReadLen​(long len)
        Converts a request to read len bytes to a lower count if reading would put us over the limit.

        If a maxCount is not set, then return maxmaxCount.

        Parameters:
        len - The requested byte count.
        Returns:
        How many bytes to actually attempt to read.
      • toString

        public java.lang.String toString()
        Invokes the delegate's Object.toString() method.
        Overrides:
        toString in class java.lang.Object
        Returns:
        the delegate's Object.toString().