4

Possible Duplicate:
Appending files to a zip file with Java

I have a zip that contains a few folders in it but the important one is dir and inside that is another folder called folder and folder contains a lot of files that I need to be able to update.

I have now a dir outside of the zip called dir and in that is folder with the files i need to update in so the paths are the same. How can i update those files into the zip?

The tricky part is that dir is at the root of the zip and it contains a lot of folders not just folder but i only need to update the files in folder i can't mess with any of the files out side of folders but still in dir.

Can this be done? I know this can be done in bash using the -u modifier but I would prefer to do this with java if it's possible.

Thank you for any help with this issue

Just to be clearer

Inside Zip /dir/folder/filestoupdate

Outside the zip /dir/folder/filestomoveintozip

Community
  • 1
  • 1
user577732
  • 3,956
  • 11
  • 55
  • 76

2 Answers2

8

Alright well here is the final method it's the same method i pastebinned before which i actually got from the stackoverflow topic in the link @Qwe posted before but i added the path variable so that it could add files to folders inside the zip

Alright so now how to use it in my example above i wanted to add a file into a folder that was inside another folder i would do that using my setup in the question like this

private void addFilesToZip(File source, File[] files, String path){
    try{
        File tmpZip = File.createTempFile(source.getName(), null);
        tmpZip.delete();
        if(!source.renameTo(tmpZip)){
            throw new Exception("Could not make temp file (" + source.getName() + ")");
        }
        byte[] buffer = new byte[4096];
        ZipInputStream zin = new ZipInputStream(new FileInputStream(tmpZip));
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(source));
        for(int i = 0; i < files.length; i++){
            InputStream in = new FileInputStream(files[i]);
            out.putNextEntry(new ZipEntry(path + files[i].getName()));
            for(int read = in.read(buffer); read > -1; read = in.read(buffer)){
                out.write(buffer, 0, read);
            }
            out.closeEntry();
            in.close();
        }
        for(ZipEntry ze = zin.getNextEntry(); ze != null; ze = zin.getNextEntry()){
            if(!zipEntryMatch(ze.getName(), files, path)){
                out.putNextEntry(ze);
                for(int read = zin.read(buffer); read > -1; read = zin.read(buffer)){
                    out.write(buffer, 0, read);
                }
                out.closeEntry();
            }
        }
        out.close();
        tmpZip.delete();
    }catch(Exception e){
        e.printStackTrace();
    }
}

private boolean zipEntryMatch(String zeName, File[] files, String path){
    for(int i = 0; i < files.length; i++){
        if((path + files[i].getName()).equals(zeName)){
            return true;
        }
    }
    return false;
}

Thanks for the link ended up being able to improve that method a bit so that it could add in files that weren't in the root and now i'm a happy camper :) hope this helps someone else out as well

EDIT I worked a bit more on the method so that it could not only append to the zip but it also is able to update files within the zip

Use the method like this

File[] files = {new File("/path/to/file/to/update/in")};
addFilesToZip(new File("/path/to/zip"), files, "folder/dir/");

You wouldn't start the path (last variable) with / as that's not how it's listed in the zip entries

user577732
  • 3,956
  • 11
  • 55
  • 76
  • renameTo is returning false in Windows..any idea why? – nation best Sep 30 '14 at 06:28
  • I have a problem with this code on line `for (ZipEntry ze = zin.getNextEntry(); ze != null; ze = zin.getNextEntry())`. It seems that `getNextEntry()` of `ZipInputStream` returns `java.util.zip.ZipEntry` while the `putNextEntry()` method of `ZipOutputStream` accepts `org.apache.tools.zip.ZipEntry`. I cannot cast or change the type of `ZipEntry`. This is the error I get: `java.lang.ClassCastException: java.util.zip.ZipEntry cannot be cast to org.apache.tools.zip.ZipEntry`. Any advice how to fix this? @user577732 – Eda Apr 14 '23 at 17:49
2

Unfortunately, Java can't update Zip files. The request to enhance that was submitted 14 years ago ;-)

You will need to unpack it to a temp folder, add files there and pack it back again.

Oleg Mikheev
  • 17,186
  • 14
  • 73
  • 95
  • well i mean i have this method already which lets me add to the zip however it only lets me add to the root but i'm not good enough with java to really improve it but here's the method http://pastebin.com/APJWMwc3 – user577732 Feb 15 '12 at 19:50
  • the issue with me extracting the zip and repacking it though is the zip has a signature on it so i wouldn't really be able to do that after i unzip it and go to rezip it – user577732 Feb 15 '12 at 19:51
  • take a look at the linked question - they recommend TrueZip - maybe it could solve your problem? – Oleg Mikheev Feb 15 '12 at 19:54
  • hopefully i'll take a look at it thanks – user577732 Feb 15 '12 at 19:58
  • well i figured this out with that method i modded it a little and got it working exactly the way i wanted it's some cool stuff so actually we can update zip files with java adding my own answer now and will explain what i did and how it works – user577732 Feb 16 '12 at 03:17