3

I am using java.util.zip to add some configuration resources into a jar file. when I call addFileToZip() method it overwrites the jar completely, instead of adding the file to the jar. Why I need to write the config to the jar is completely irrelevant. and I do not wish to use any external API's.

EDIT: The jar is not running in the VM and org.cfg.resource is the package I'm trying to save the file to, the file is a standard text document and the jar being edited contains the proper information before this method is used.

My code:

public void addFileToZip(File fileToAdd, File zipFile)
{
    ZipOutputStream zos = null;
    FileInputStream fis = null;
    ZipEntry ze = null;
    byte[] buffer = null;
    int len;

    try {
        zos = new ZipOutputStream(new FileOutputStream(zipFile));
    } catch (FileNotFoundException e) {
    }

    ze = new ZipEntry("org" + File.separator + "cfg" + 
            File.separator + "resource" + File.separator + fileToAdd.getName());
    try {
        zos.putNextEntry(ze);

        fis = new FileInputStream(fileToAdd);
        buffer = new byte[(int) fileToAdd.length()];

        while((len = fis.read(buffer)) > 0)
        {
            zos.write(buffer, 0, len);
        }           
    } catch (IOException e) {
    }
    try {
        zos.flush();
        zos.close();
        fis.close();
    } catch (IOException e) {
    }
}
  • possible duplicate of [Appending files to a zip file with Java](http://stackoverflow.com/questions/2223434/appending-files-to-a-zip-file-with-java) – McDowell Jul 06 '13 at 12:26
  • It is a duplicate, but the answers to the other question asked 3 years ago does not mention zip file system that. Zip file system first appeared in Java 7. – Grzegorz Żur Jul 06 '13 at 13:45

1 Answers1

4

The code you showed overrides a file no matter if it would be a zip file or not. ZipOutputStream does not care about existing data. Neither any stream oriented API does.

I would recommend

  1. Create new file using ZipOutputStream.

  2. Open existing with ZipInputStream

  3. Copy existing entries to new file.

  4. Add new entries.

  5. Replace old file with a new one.


Hopefully in Java 7 we got Zip File System that will save you a lot of work.

We can directly write to files inside zip files

Map<String, String> env = new HashMap<>(); 
env.put("create", "true");
Path path = Paths.get("test.zip");
URI uri = URI.create("jar:" + path.toUri());
try (FileSystem fs = FileSystems.newFileSystem(uri, env))
{
    Path nf = fs.getPath("new.txt");
    try (Writer writer = Files.newBufferedWriter(nf, StandardCharsets.UTF_8, StandardOpenOption.CREATE)) {
        writer.write("hello");
    }
}
Grzegorz Żur
  • 47,257
  • 14
  • 109
  • 105
  • okay, ill take a shot at it tommorow and ill get back to you on how it goes, sounds like it would work and thanks for the help. +1 for info and possible fix. –  Jul 06 '13 at 07:54
  • @user1718720 Check the answer again, I added Zip File System, that will save you a lot of work. – Grzegorz Żur Jul 06 '13 at 07:58
  • for this do the files allready have to exist inside the zip? its no problem to add blanks ahead of time, the point is to change the contents of the files. –  Jul 06 '13 at 16:32
  • @user1718720 This example creates files if they do not exist. This is thanks to `StandardOpenOption.CREATE`. See other options to get the behavior you need. – Grzegorz Żur Jul 06 '13 at 16:38