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

GZIPInputStream's available() reports 1, but read() gives -1.

XMLWordPrintable

    • b128
    • x86
    • windows_2008

      FULL PRODUCT VERSION :
      java version "1.6.0_21"
      Java(TM) SE Runtime Environment (build 1.6.0_21-b07)
      Java HotSpot(TM) 64-Bit Server VM (build 17.0-b17, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      The following unit test snippet fails as is:

      // a) InputStream is = new FileInputStream(f1);
      InputStream is = new GZIPInputStream(new FileInputStream(f1));
      try {
      do {
      //Skip
      if (is.available() > 0) {
      assertTrue(is.read() != -1);
      } else {
      assertTrue(is.read() == -1);
      assertTrue(is.available() == 0);
      break;
      }

      } while (true);

      } finally {
      is.close();
      }

      If we uncomment a) and comment the line after it, the test passes.
      1) This hints a possible inconsistency between the input stream and the gzip-wrapped input stream.
      2) According to the documentation, when available() tells we have something to take it returns a non-zero value, and a subsequent read() gives a byte from that something. This seems broken at the end of gzipped streams.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the unit test, completing it with supplying a gzipped file.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Test passes.
      ACTUAL -
      Test fails.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Test fails at
      assertTrue(is.read() != -1);

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      @Test
      public final void testGzippedStreamAPIConsistency() throws IOException {
      File f1 = new File("bla01.gz");
      writeOperationsZipFile(f1, 20);

      // a) InputStream is = new FileInputStream(f1);
      InputStream is = new GZIPInputStream(new FileInputStream(f1));
      try {
      do {
      //Skip
      if (is.available() > 0) {
      assertTrue(is.read() != -1);
      } else {
      assertTrue(is.read() == -1);
      assertTrue(is.available() == 0);
      break;
      }

      } while (true);

      } finally {
      is.close();
      }
      }

      private void writeOperationsZipFile(File f, final int howMany) throws IOException {
      OutputStream fos = new GZIPOutputStream(new FileOutputStream(f));
      try {
      writeOutputStream(fos, howMany);
      } finally {
      fos.close();
      }
      }
      private void writeOutputStream(OutputStream fos, int howMany) {
      PrintStream ps = new PrintStream(fos);

      try {
      int i = 0;
      while (i < howMany) {
      //write an operation.
      ps.println("operation" + i);
      i++;
      }//while
      } finally {
      ps.close();
      }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Do not rely on available() but on the return result of read().

            sherman Xueming Shen
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: