简体   繁体   中英

java - Progress Bar while download with FileUtils

I'm trying to download a large file from URL with commons.io Apache library . This is my code:

    InputStream stream = new URL(CLIENT_URL).openStream();
    ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(null, "Downloading...", stream);
    ProgressMonitor pm = pmis.getProgressMonitor();
    pm.setMillisToDecideToPopup(0);
    pm.setMillisToPopup(0);
    FileUtils.copyInputStreamToFile(pmis, new File(LATEST_FILENAME));
    pmis.close();
    stream.close();

But it doesn't show the popup. Or, to be honest, the popup appear and disappear only for a millisec, while the download take about 10secs.

A generic InputStream does not provide information about the current position or the total length to the outside wold. See InputStream availiable() is not the total size of the InputStream and there is no such thing like get current position or get total size. You also might read only chunks / parts of the stream, even the progress bar would be able to figure out the total length of the stream it will not know that you are only going to read for example 512 bytes.

The ProcessMonitorInputStream decorates the provided InputStream and updates the progress bar of the dialog box during the read operation. Per default the ProgressMonitorInputStream use available of the passed InputStream to initialise the max value of the ProgressMonitor . The value may be correct for some InputStreams but is not especially when you transfer data via network.

available() returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream.

This initial max value is also the reason why you sometimes see the dialog box. The dialog closes automatically after the max value of the progress bar is reached. In order to display anything useful you must give the ProgressMonitor some hints about the start position and the end position in form of setMinimum and setMaximum .

     // using a File just for demonstration / testing
     File f = new File("a");
     try (InputStream stream = new FileInputStream(f)) {
        ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(null, "Downloading...", stream);
        int downloadSize = f.length();
        ProgressMonitor pm = pmis.getProgressMonitor();
        pm.setMillisToDecideToPopup(0);
        pm.setMillisToPopup(0);
        // tell the progress bar that we start at the beginning of the stream
        pm.setMinimum(0);
        // tell the progress bar the total number of bytes we are going to read.    
        pm.setMaximum(downloadSize);
        copyInputStreamToFile(pmis, new File("/tmp/b"));
     }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM