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

ProgressMonitorInputStream not large file aware (>2GB)

    XMLWordPrintable

Details

    • b12
    • x86
    • linux

    Backports

      Description

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


        ADDITIONAL OS VERSION INFORMATION :
        Linux speedy 2.6.16-mjsmjs #1 SMP Wed Apr 5 10:50:33 CDT 2006 x86_64 x86_64 x86_64 GNU/Linux

        A DESCRIPTION OF THE PROBLEM :
        ProgressMonitorInputStream fails to accurately report progress; the progress bar "cycles" several times from 0 to 100% complete on large (>2 GB) files. The problem lies in the ProgressMonitorInputStream class, which uses a 32 bit int to store progress and file size. File size is obtained from the InputStream using available() (see bug 4711604) and is not (and cannot be for files > 2GB) indicative of actual file size. As a result, the progress variable overflows and the progress bar is empty for some time and then starts over at 0.
        Files this large are not uncommon- e.g. seismic data, movies, etc.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Compile attached source. Run with large file as parameter (>2GB).

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        Progress monitor should go from 0% to 100% when entire file is read.
        ACTUAL -
        Progress monitor goes to 100% at 2GB, then back to 0%, stays at 0% until 4GB is reached, then goes from 0% to 100% at 6 GB, etc. User has no idea how long entire file will take or may think process is "hung" after 2GB.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.io.FileInputStream;
        import java.io.FileNotFoundException;
        import java.io.IOException;

        import javax.swing.ProgressMonitorInputStream;

        public class ProgressMonitorInputStreamTest {

        public static void main(String[] args) {

        final ProgressMonitorInputStream pmis;
        try {
        FileInputStream fileIn=new FileInputStream(args[0]);
        pmis=new ProgressMonitorInputStream(null, "Reading File", fileIn);
        } catch (FileNotFoundException e) {
        e.printStackTrace();
        return;
        }
        byte[] buffer=new byte[512];
        int nb;
        long total=0;
        try {
        while (true) {
        nb=pmis.read(buffer);
        if (nb==0) break;
        total+=nb;
        pmis.getProgressMonitor().setNote(total/(1024*1024)+" MB Read");
        }
        } catch (IOException ioe) {
        ioe.printStackTrace();
        }
        }
        }

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

        CUSTOMER SUBMITTED WORKAROUND :
        I've changed the ProgressMonitorInputStream class to "scale" the progress to 32 bits (so ProgressMonitor can use it) after obtaining the file size using FileChannel.size() if the input parameter to ProgressMonitorInputStream constructor is instanceof FileInputStream.

        Attachments

          Issue Links

            Activity

              People

                psadhukhan Prasanta Sadhukhan
                rmandalasunw Ranjith Mandala (Inactive)
                Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: