7

Problem

I have an existing zipfile "main.zip". I want to replace a single file in it, "say main.zip/foo."

I am aware of:

http://docs.oracle.com/javase/7/docs/api/java/util/zip/ZipOutputStream.html

However, this does not do what I want, as it creates a new Zip file -- and thus I'd have to add in all the existing entries in main.zip also.

Question:

Is there a way to "replace" a single file within a Zip archive in Java? (Without re-creating a new zip archive and copying over all the old data).

rekire
  • 47,260
  • 30
  • 167
  • 264
  • possible duplicate of [Java appending files into a zip](http://stackoverflow.com/questions/9300115/java-appending-files-into-a-zip) – Frank van Puffelen Dec 09 '12 at 12:37
  • From one of those questions comes this most succinct summary: "Unfortunately, Java can't update Zip files... You will need to unpack it to a temp folder, add files there and pack it back again." – Frank van Puffelen Dec 09 '12 at 12:39
  • @FrankvanPuffelen: My question is a dup. I think we should close (but not delete) the question. –  Dec 09 '12 at 15:02

1 Answers1

23

I think you are in luck.

Using the java 7 java.nio.file.FileSystem together with Files.copy() I managed to insert a textfile into a large zipfile in a split second.

public static void main(String[] argv) {
    Path myFilePath = Paths.get("c:/dump2/mytextfile.txt");

    Path zipFilePath = Paths.get("c:/dump2/myarchive.zip");
    try( FileSystem fs = FileSystems.newFileSystem(zipFilePath, null) ){
        Path fileInsideZipPath = fs.getPath("/mytextfile.txt");
        Files.copy(myFilePath, fileInsideZipPath);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

It 'mounts' the zip using the ZipFileSystem Provider. Then you can just copy whatever you want into it. The changes seem to take place on fs.close()

Read more @ oracle

kritzikratzi
  • 19,662
  • 1
  • 29
  • 40
Aksel Willgert
  • 11,367
  • 5
  • 53
  • 74
  • I like. (Learning about java.nio.file.FileSystem is especially cool). Thanks1 –  Dec 09 '12 at 15:01
  • hey @AkselWillgert could you help me whit [this](http://stackoverflow.com/questions/14647152/writing-modifying-or-adding-a-file-inside-a-zip#comment20464753_14647152)? – Ordiel Feb 01 '13 at 13:23
  • Unfortunately, the ZipFileSystem will run out of memory when trying to use Files.copy to add a large file in this manner. – Coke Mar 28 '13 at 19:15
  • Think I tried it for relatively large files, but might recall incorrectly. What sizes and computer system are you talking about here? – Aksel Willgert Mar 28 '13 at 19:32
  • 2
    Thanks this is what I was looking for. By using this method I can add the txt file to the main folder of zip but I can't go deeper. I want to add a txt file into a folder which is inside the zip file. When I change the code to Path fileInsideZipPath = fs.getPath("res/raw/mytextfile.txt"); I get java.nio.file.NoSuchFileException: res/raw. Do you know a method to manage this? – irmakoz Jun 12 '13 at 13:56
  • does the folder exist otherwise you need to create it. I think the names inside the zip are case-sensitive also – Aksel Willgert Jun 12 '13 at 14:11
  • Yes, the folder exists and all names are lower case. – irmakoz Jun 13 '13 at 06:47
  • Thank you very much, Aksel Willgert. – Arthur Jun 08 '14 at 12:08
  • 1
    If the file already exists in the zip file, you will get a `java.nio.file.FileAlreadyExistsException`. In this case you have to add a `CopyOption` like this: `Files.copy(myFilePath, fileInsideZipPath, StandardCopyOption.REPLACE_EXISTING);` –  Jan 12 '22 at 07:15