Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8264225

Unexpected return value for java.io.SequenceInputStream available()

XMLWordPrintable

      A DESCRIPTION OF THE PROBLEM :
      The return value of SequenceInputStream available() isn't correct if the next substream in the sequence is empty.

      From the docs of the parent class InputStream, the return value of available() should be "an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking or 0 when it reaches the end of the input stream." Emphasis on 0 when it reaches the end of the stream. This means the available() function should only return 0 when there are no more bytes to be read from the stream.

      The current implementation of SequenceInputStream returns the result of the next substream's available() without checking the return value. If the next substream in the sequence is empty, the current implementation of SequenceInputStream returns 0, indicating the end of the stream, even though there might still be bytes in the remaining substreams.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Call available() on a SequenceInputStream when the current substream is empty but bytes are available in any remaining substream in the sequence.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The return value of SequenceInputStream available() should be > 0.
      ACTUAL -
      The return value of SequenceInputStream available() is 0.

      ---------- BEGIN SOURCE ----------
      import java.io.ByteArrayInputStream;
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.SequenceInputStream;

      public class Main {
          public static void main(String[] args) throws IOException {
              InputStream nonEmptyByteStream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
              InputStream emptyByteStream = new ByteArrayInputStream(new byte[0]);
              SequenceInputStream myStream = new SequenceInputStream(emptyByteStream, nonEmptyByteStream);
              System.out.println(myStream.available()); // returns 0, indicating end of stream
              myStream.read(); // doesn't return -1 because bytes are still in stream
              System.out.println(myStream.available()); // no longer returns 0 even though no bytes have been written to stream
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      One workaround is to not trust the return value of the available() function if it returns 0 because it could be a false negative. If available() returns 0, just attempt to read a byte by calling read() and see if the return value is -1 or not.

      The a potential permanent fix for SequenceInputStream is to continually loop through the substreams while the return value of each substream's available() is 0 until either all streams have been exhausted or a substream with a non-zero available() return value is encountered.

      FREQUENCY : often


            michaelm Michael McMahon
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: