简体   繁体   中英

Java how to turn zip file into regular java.io.File with folders and files

I am working on method that will turn zipped file into regular java.io.File with all files and folders in same order as in zip. Basically I just want to unzip zipped file without copying its content into new destination. I have already come up with this function that so far works pretty well but only if there are no folders in zip. Files in zip cant be directories or my function will not work and that is the problem.
Here is my function:

File unzip(File zip) throws IOException
    {
        ZipInputStream zis = new ZipInputStream(new FileInputStream(zip));
        
        //helper directory to store files into while program is running!
        File helperDir = Files.createDirectories(Paths.get("zipFile")).toFile();  
        //helperDir.deleteOnExit();
        
        byte[] buffer = new byte[1024];
        for (ZipEntry entry; (entry = zis.getNextEntry()) != null; )
        {
            if (!entry.isDirectory()) //true if file in zip is not a folder
            {
                File newFile = new File(helperDir, entry.getName());
                //newFile.deleteOnExit();
                
                FileOutputStream fos = new FileOutputStream(newFile);
                for (int len = zis.read(buffer); len > 0; len = zis.read(buffer))
                    fos.write(buffer, 0, len);
                fos.close();
            }
            else
            {
                //What to do if there are folders in zip...
            }
        }
        
        zis.close();
        return helperDir;
    }

How can I handle the folders in zip? Or if there is a better way to turn zip into java.io.File than how?
Please help!

You only need a little bit more to setup the directory once you have found one. Either create the required dirs using one line newFile.mkdirs() just before file copy, or make the directory structure in the else when entry.isDirectory() :

//What to do if there are folders in zip...
System.out.println("Reading dir  "+entry.getName());
File newDir = new File(helperDir, entry.getName());
newDir.mkdirs();

The above 3 lines is better as it reproduces empty directories, whereas just adding newFile.mkdirs() only creates directories which have files in them.

Java NIO provides a nice way of doing the same unzip operation, here is an example:

public static void unzip(Path zip, Path dir) throws IOException {
    try (FileSystem fs = FileSystems.newFileSystem(zip)) {
        for (Path root : fs.getRootDirectories()) {
            BiPredicate<Path, BasicFileAttributes> foreach = (p,a) -> {
                copy(p,a, Path.of(dir.toString(), p.toString()));
                return false;
            };
            Files.find(root, Integer.MAX_VALUE, foreach).count();
        }
    }
    System.out.println("UNZIPPED "+zip +" to "+dir);
}
private static void copy(Path from, BasicFileAttributes a, Path target)  {
    System.out.println("Copy "+(a.isDirectory() ? "DIR " : "FILE")+" => "+target);
    try {
        if (a.isDirectory())
            Files.createDirectories(target);
        else if (a.isRegularFile())
            Files.copy(from, target, StandardCopyOption.REPLACE_EXISTING);
    }
    catch (IOException e) {
        throw new UncheckedIOException(e);
    }
}

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