0

I have a method which has access to the zip file's name and the zipInputStream object (The zipInputStream actually comes from a service which cannot take any additional changes). I want to save the contents of the zipInputStream as a ZIP file in a particular path on my system. Can someone help me with the best way to do this?

PS: I'm still finding my way around java

Arjun
  • 108
  • 9

1 Answers1

1

Warning: The below causes each entry in the source ZIP file to be decompressed, only to immediately recompress it when copying it to the target ZIP file. As far as I can tell, this is unavoidable if all you have access to is the ZipInputStream. Perhaps someone else knows of a better approach. I would recommend modifying your code to somehow get the raw byte stream of the ZIP file, that way you can just dump the bytes into your target file.


If I understand your goal correctly, you want to copy a ZIP file from one location to another, but you only have access to the ZIP file via a ZipInputStream. If that's the case, then you can implement this by opening a ZipOutputStream to the target file and copying the entries over.

For example:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class Main {

  public static void copyZipFile(ZipInputStream in, File target) throws IOException {
    try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(target))) {
      byte[] buffer = new byte[1024 * 8];

      ZipEntry entry;
      while ((entry = in.getNextEntry()) != null) {
        out.putNextEntry(entry);
        
        int read;
        while ((read = in.read(buffer)) != -1) {
          out.write(buffer, 0, read);
        }
      }
    }
  }

  public static void main(String[] args) {
    File target = /* your target file */;
    try (ZipInputStream in = /* your ZipInputStream */) {
      copyZipFile(in, target);
    } catch (IOException ex) {
      ex.printStackTrace();
    }
  }
}

It's important you close the streams when done with them (which is done via try-with-resources in the above example).

Note the manual buffer handling can be replaced with InputStream#transferTo(OutputStream) in Java 9+.

Slaw
  • 37,820
  • 8
  • 53
  • 80
  • Would there be an alternative for `transferTo` if I'm on Java 8 ? – Arjun Jul 07 '22 at 09:25
  • 1
    Updated answer to show an alternative to `transferTo`. I also added a warning about how the data is being decompressed only to be immediately recompressed. This happens regardless of using `transferTo` or not. – Slaw Jul 08 '22 at 03:09