简体   繁体   中英

Get progress of unzipping file in java

So I'm making a downloader and unzipper for a game, but I am not able to get the progress of the unzipping. This is my unzip method:

static public void unzip(cachePart name) throws ZipException, IOException {
        System.out.println("Unzipping " + name.getFile());
        int BUFFER = 2048;
        long current = 0;
        File file = new File(name.getFilePath());

        ZipFile zip = new ZipFile(file);
        //String newPath = zipFile.substring(0, zipFile.length() - 4);

        int finalSize = zip.size();

        //new File(newPath).mkdir();
        Enumeration<?> zipFileEntries = zip.entries();

        // Process each entry
        while (zipFileEntries.hasMoreElements()) {

            // grab a zip file entry
            ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
            current += entry.getCompressedSize();
            //long finalSize = entry.getSize();
            int percentage;
            String currentEntry = entry.getName();
            File destFile = new File(Data.SAVE_DIR, currentEntry);
            //destFile = new File(newPath, destFile.getName());
            File destinationParent = destFile.getParentFile();

            // create the parent directory structure if needed
            destinationParent.mkdirs();

            if (!entry.isDirectory()) {
                BufferedInputStream is = new BufferedInputStream(zip.getInputStream(entry));
                int currentByte;
                // establish buffer for writing file
                byte data[] = new byte[BUFFER];

                // write the current file to disk
                FileOutputStream fos = new FileOutputStream(destFile);
                BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);

                // read and write until last byte is encountered
                while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
                    dest.write(data, 0, currentByte);
                }
                percentage = (int) (current / finalSize * 100);
                System.out.println("finalSize " + finalSize);
                System.out.println("Current " + current);
                System.out.println("percentage " + percentage + "%");

                dest.flush();
                dest.close();
                is.close();
            }
        }
        zip.close();
        System.out.println("Done unzipping " + name.getFile());
    }

So I tried to do some things, but I can't get the 2 different sizes I need. Which I think are: The size of the uncompressed zip file and the size of the next file it's going to unzip. I tried doing this with:

int finalSize = zip.size();

and

current += entry.getCompressedSize();

You could try using Zip4j . It comes with a progress monitor and has worked well for me in the past.

Here is an example from their forums showing how to use it. The example demonstrates zipping but the progress monitor works the same way for unzipping, as well.

import java.io.File;
import java.util.ArrayList;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.progress.ProgressMonitor;
import net.lingala.zip4j.util.Zip4jConstants;

/**
 * This example demonstrates ProgressMonitor usage. Progress Monitor
 * can be used to get the current progress information of the task
 * being performed by Zip4j.<br><br>
 * 
 * ProgressMonitor can be used to get information regarding any kind of task.
 * This example uses the adding files to Zip functionality. Information regarding
 * rest of the tasks is similar to this approach 
 */
public class ProgressInformation {

    public ProgressInformation() {

        try {
            // Initiate the ZipFile
            ZipFile zipFile = new ZipFile("c:\\ZipTest\\ProgressInformation.zip");

            // Set runInThread variable of ZipFile to true.
            // When this variable is set, Zip4j will run any task in a new thread
            // If this variable is not set, Zip4j will run all tasks in the current
            // thread. 
            zipFile.setRunInThread(true);

            // Initialize files to add
            ArrayList filesToAdd = new ArrayList();
            filesToAdd.add(new File("c:\\ZipTest\\sample.txt"));
            filesToAdd.add(new File("c:\\ZipTest\\myvideo.avi"));
            filesToAdd.add(new File("c:\\ZipTest\\mysong.mp3"));

            // Initialize Zip Parameters
            ZipParameters parameters = new ZipParameters();
            parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
            parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); 

            // Add files to Zip
            zipFile.addFiles(filesToAdd, parameters);

            // Get progress monitor from ZipFile
            ProgressMonitor progressMonitor = zipFile.getProgressMonitor();

            // PLEASE NOTE: Below code does a lot of Sysout's.

            // ProgressMonitor has two states, READY and BUSY. READY indicates that
            // Zip4j can now accept any new tasks. BUSY indicates that Zip4j is
            // currently performing some task and cannot accept any new task at the moment
            // Any attempt to perform any other task will throw an Exception
            while (progressMonitor.getState() == ProgressMonitor.STATE_BUSY) {
                // ProgressMonitor has a lot of useful information like, the current
                // operation being performed by Zip4j, current file being processed,
                // percentage done, etc. Once an operation is completed, ProgressMonitor
                // also contains the result of the operation. If any exception is thrown
                // during an operation, this is also stored in this object and can be retrieved
                // as shown below

                // To get the percentage done
                System.out.println("Percent Done: " + progressMonitor.getPercentDone());

                // To get the current file being processed
                System.out.println("File: " + progressMonitor.getFileName());

                // To get current operation
                // Possible values are:
                // ProgressMonitor.OPERATION_NONE - no operation being performed
                // ProgressMonitor.OPERATION_ADD - files are being added to the zip file
                // ProgressMonitor.OPERATION_EXTRACT - files are being extracted from the zip file
                // ProgressMonitor.OPERATION_REMOVE - files are being removed from zip file
                // ProgressMonitor.OPERATION_CALC_CRC - CRC of the file is being calculated
                // ProgressMonitor.OPERATION_MERGE - Split zip files are being merged
                switch (progressMonitor.getCurrentOperation()) {
                case ProgressMonitor.OPERATION_NONE:
                    System.out.println("no operation being performed");
                    break;
                case ProgressMonitor.OPERATION_ADD:
                    System.out.println("Add operation");
                    break;
                case ProgressMonitor.OPERATION_EXTRACT:
                    System.out.println("Extract operation");
                    break;
                case ProgressMonitor.OPERATION_REMOVE:
                    System.out.println("Remove operation");
                    break;
                case ProgressMonitor.OPERATION_CALC_CRC:
                    System.out.println("Calcualting CRC");
                    break;
                case ProgressMonitor.OPERATION_MERGE:
                    System.out.println("Merge operation");
                    break;
                default:
                    System.out.println("invalid operation");
                    break;
                }
            }

            // Once Zip4j is done with its task, it changes the ProgressMonitor
            // state from BUSY to READY, so the above loop breaks.
            // To get the result of the operation:
            // Possible values:
            // ProgressMonitor.RESULT_SUCCESS - Operation was successful
            // ProgressMonitor.RESULT_WORKING - Zip4j is still working and is not 
            //                                  yet done with the current operation
            // ProgressMonitor.RESULT_ERROR - An error occurred during processing
            System.out.println("Result: " + progressMonitor.getResult());

            if (progressMonitor.getResult() == ProgressMonitor.RESULT_ERROR) {
                // Any exception can be retrieved as below:
                if (progressMonitor.getException() != null) {
                    progressMonitor.getException().printStackTrace();
                } else {
                    System.err.println("An error occurred without any exception");
                }
            }

        } catch (ZipException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new ProgressInformation();
    }

}

The correct example is:

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import java.util.List;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.progress.ProgressMonitor;

public class Test {

    public static void main(String[] args) {
        Test.unzip();
    }

    public static void unzip() {
        String source = "D:\\Downloads\\file.zip";
        String destination = "D:\\Downloads\\folder\\";

        try {
            ZipFile zipFile = new ZipFile(source);
            ProgressMonitor progressMonitor = zipFile.getProgressMonitor();

            List fileHeaderList = zipFile.getFileHeaders();
            for (int i = 0; i < fileHeaderList.size(); i++) {
                FileHeader fileHeader = (FileHeader) fileHeaderList.get(i);

                System.out.println("Progress: " + (i + 1) + " / " + fileHeaderList.size());
                System.out.println("File: " + fileHeader.getFileName());

                zipFile.extractFile(fileHeader, destination);
            }
        } catch (ZipException e) {
            e.printStackTrace();
        }
    }
}

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