Skip to Main Content

Java Programming

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Nested Zip files using Java.Util.Zip

807603Dec 13 2007 — edited Dec 13 2007
I am having a rather nasty problem with Java.Util.Zip and/or my code. I am able to fully zip a file with the code and then unzip it intact with either the unzip method listed or windows zip utility. However when I try to construct a zip within a zip, upon extraction using the windows utility I cannot see the contents of the nested zip, and the explorer window crashes (after showing a blank archive) soon after I have double clicked the file to open.

Unzipping the nested files using the code only, "test_out.pdf" is fully intact and viewable.

Here is my test code:
        Map<String, byte[]> zipThis = new HashMap<String, byte[]>();
        zipThis.put("/xml/test.xml", "<A><B><C><D>test</D></C></B></A>".getBytes());
        zipThis.put("/manifest/manifest.xml", "<A><B><C><D>manifest</D></C></B></A>".getBytes());
        zipThis.put("/attachment/test.pdf", IOUtils.byteSafeRead("test.pdf"));
        byte[] inter = ZipUtils.zipFiles(zipThis);

        IOUtils.byteSafeWrite(inter, "nested.zip");
        
        Map<String, byte[]> zipThis2 = new HashMap<String, byte[]>();
        zipThis2.put("nested.zip", inter);
        
        byte[] finalZip = ZipUtils.zipFiles(zipThis2);
        
        IOUtils.byteSafeWrite(finalZip, "finalZip.zip");

        Map<String, byte[]> filesz = ZipUtils.unzipFiles(finalZip);
        Map<String, byte[]> filesz2 = ZipUtils.unzipFiles(filesz.get("nested.zip"));

        IOUtils.byteSafeWrite(filesz2.get("/attachment/test.pdf"), "test_out.pdf");
Here is the code that was constructed to zip and unzip byte arrays:
 
public static byte[] zipFiles(Map<String, byte[]> files)
            throws Exception {

        // Used to create byte array from resulting zip
        ByteArrayOutputStream dest = new ByteArrayOutputStream();

        // The stream that will contain our zip file representation
        ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));

        // Buffer
        byte data[] = new byte[2048];

        Iterator<String> itr = files.keySet().iterator();

        //Insert files 
        while (itr.hasNext()) {
            String tempName = itr.next();
            byte[] tempFile = files.get(tempName);

            ByteArrayInputStream bytesIn = new ByteArrayInputStream(tempFile);
            // Take one InputStream from array as a new file to add to zip
            BufferedInputStream origin = new BufferedInputStream(bytesIn, 2048);

            // Name entry using key in map
            ZipEntry entry = new ZipEntry(tempName);
            out.putNextEntry(entry);

            // Write ByteArrayInputStream contents to zip output
            int count;
            while ((count = origin.read(data, 0, 2048)) != -1) {
                out.write(data, 0, count);
            }
            bytesIn.close();
            origin.close();
        }
        out.close();

        byte[] outBytes = dest.toByteArray();

        dest.close();

        // Return zip as byte[]
        return outBytes;

    }
and to unzip:
 public static Map<String, byte[]> unzipFiles(byte[] zipBytes)
            throws IOException {

        // Get an input stream so we can use util.zip stuff
        InputStream bais = new ByteArrayInputStream(zipBytes);

        // Unzip the input stream
        ZipInputStream zin = new ZipInputStream(bais);

        ZipEntry ze;

        Map<String, byte[]> extractedFiles = new HashMap<String, byte[]>();

        // Loop through each zip entry
        while ((ze = zin.getNextEntry()) != null) {

            ByteArrayOutputStream toScan = new ByteArrayOutputStream();

            // Transfer bytes from the ZIP file to the output 
            byte[] buf = new byte[1024];
            int len;
            while ((len = zin.read(buf)) > 0) {
                toScan.write(buf, 0, len);
            }

            // This byte array contains one file from archive
            byte[] fileOut = toScan.toByteArray();
            toScan.close();
            extractedFiles.put(ze.getName(), fileOut);

        }
        zin.close();
        bais.close();

        return extractedFiles;
    }
Using this code exclusively to zip and unzip a file, everything works, I can also open the file in windows using its native zip utility.

Note that I have a simple method that dumps these byte arrays to a file:
    public static void byteSafeWrite(byte[] arr, String file)
            throws Exception {

        File someFile = new File(file);
        FileOutputStream fos = new FileOutputStream(someFile);
        fos.write(arr);
        fos.flush();
        fos.close();
    }
And a method to read files I want to include
    public static byte[] byteSafeRead(String file)
            throws Exception {

        FileInputStream fis = new FileInputStream(file);
        FileChannel fc = fis.getChannel();
        byte[] data = new byte[(int) fc.size()];
        ByteBuffer bb = ByteBuffer.wrap(data);
        fc.read(bb);
        return data;
    }
I am guessing my problem may relate the the streams I am juggling around. If anyone has any insight into what may be causing this I would be most grateful to get an answer!

Thanks for your time in advance!!

Edited by: mjgagne on Dec 13, 2007 9:22 AM
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jan 10 2008
Added on Dec 13 2007
0 comments
1,513 views