hfrog713
hfrog713

Reputation: 410

Write to subdir in Zip? Using java.util.zip. ZipEntry.putNextEntry()

So i created a zip and created a new sub folder in the zip file by creating a zip entry that ends in "\". How would i write to the subfolder?

My problem is i have a putnextEntry call on my ZipOutputStream in a for loop so after the folder gets created i then jump into a for loop where the different zip files are written. But they are written at the same level as the subdir within the zip.

What i think is happening is because i use putNextEntry with the first actual zip(not dir) entry it is closing the subfolder and writing to the root of the zip. Any ideas?

Code below

private int endprocess() {
        try {
            zipFolder(ripPath, zipOutputPath, "rips");
            //zipFolder(destPDFfiles, zipOutputPath, "pdfs");
            this.returnCode = 0;
            //log.debug ( "Accumulator count: " + acount);
            log.debug("Equivest count: " + ecount);
            //log.debug ( "Assoc count: " + scount);
            processEndOfEnvelope();
        } catch (Exception reportException) {
            log.logError("Caught exception in creating.");
            reportException.printStackTrace();
            this.returnCode = 15;
        }

        return (this.returnCode);

    }
    public static void zipFolder(String srcFolder, String dest, String outputFolder){
        try{
            ZipOutputStream zos = null;
            FileOutputStream fos = null;
            fos = new FileOutputStream(dest + "\\newzip.zip");
            zos = new ZipOutputStream(fos);
            addFolderToZip(srcFolder, zos, outputFolder);
            zos.flush();
            zos.close();
        }catch(IOException e){
            log.logError("**********************");
            log.logError("IO Exception occurred");
            log.logError(e.getMessage());
            e.printStackTrace();
        }
    }
    private static void addFileToZip(String srcFile, ZipOutputStream zos, String outputFolder){
        try {
            File folder = new File(srcFile);
            if (folder.isDirectory()) {
                addFolderToZip(srcFile, zos, outputFolder);
            } else {
                byte[] buffer = new byte[1024];
                int length;
                FileInputStream fis = new FileInputStream(srcFile);
                ZipEntry ze = new ZipEntry("C:\\AWDAAV\\zip\\newzip.zip\\" + outputFolder + "\\" + folder.getName());
                zos.putNextEntry(ze);
                while ((length = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, length);
                }
            }
        }catch(Exception e){
            log.logError("**********************");
            log.logError("Exception occurred");
            log.logError(e.getMessage());
            e.printStackTrace();
        }
    }

    private static void addFolderToZip(String srcFolder, ZipOutputStream zos, String outputFolder){
        try{
            File folder = new File(srcFolder);
            zos.putNextEntry(new ZipEntry(outputFolder + "\\"));
            for(String fileName : folder.list()){
                addFileToZip(srcFolder + "\\" + fileName, zos, outputFolder);
            }
        }catch(Exception e){
            log.logError("**********************");
            log.logError("Exception occurred");
            log.logError(e.getMessage());
            e.printStackTrace();
        }
    }

Upvotes: 1

Views: 1142

Answers (2)

David
David

Reputation: 1296

I had a look at your code and i think the ZIP API works just as you think.

Only you had some logic errors with the path names. You need to convert the path names from the local names to the relative locations in the zip file. Maybe you got confused somewhere in that area.

Here is my suggestion:

File: org/example/Main.java

package org.example;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Main {

    public static void main(String[] args) throws IOException {
        MyZip myZip = new MyZip();
        Path sourcePath = Paths.get("C:/Users/David/Desktop/a");
        Path targetPath = Paths.get("C:/Users/David/Desktop/zip/out.zip");
        Path zipPath = Paths.get("tadaa");
        myZip.zipFolder(sourcePath, targetPath.toFile(), zipPath);
    }

}

Update: Explanation of variables in main method

  • The sourcePath is a directory which content you want to include in the zip archive.
  • The targetPath is the output path of the zip file. For example the new zip file will be created at exactly that location.
  • The zipPath is the subdirectory within the zip directory where your content from sourcePath will be placed. This variable may also be set to null. If it is null the sourcePath will be put in the root of the new zip archive.

File: org/example/MyZip.java

package org.example;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class MyZip {

    public void zipFolder(Path base, File dest, Path zipFolder) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(dest);
                ZipOutputStream zos = new ZipOutputStream(fos)) {
            addFolderToZip(base.getParent(), base, zos, zipFolder);
        }
    }

    private void addFolderToZip(Path base, Path currentFolder, ZipOutputStream zos, Path zipFolder) throws IOException {
        try (DirectoryStream<Path> stream = Files.newDirectoryStream(currentFolder)) {
            for(Path path : stream) {
                Path relativePath = base != null ? base.relativize(path) : path;
                Path pathInZip = zipFolder != null ? zipFolder.resolve(relativePath) : relativePath;
                if(path.toFile().isDirectory()) {
                    zos.putNextEntry(new ZipEntry(pathInZip.toString() + "/"));
                    // recurse to sub directories
                    addFolderToZip(base, path, zos, zipFolder);
                } else {
                    addFileToZip(path, pathInZip, zos);
                }
            }
        }
    }

    private void addFileToZip(Path sourcePath, Path pathInZip, ZipOutputStream zos) throws IOException {
        byte[] buffer = new byte[1024];
        int length;
        try (FileInputStream fis = new FileInputStream(sourcePath.toFile())) {
            ZipEntry ze = new ZipEntry(pathInZip.toString());
            zos.putNextEntry(ze);
            while ((length = fis.read(buffer)) > 0) {
                zos.write(buffer, 0, length);
            }
        }
    }

}

Upvotes: 1

Rocket6488
Rocket6488

Reputation: 103

ZipEntry.setLevel(filepath[in your case, \folder]);

Upvotes: 0

Related Questions