0

I have seen posts about how to unzip files using Java, where the zip file is located somewhere on disk. In my case it's different.

I have code which calls a soap web service. The service response includes an attachment which is a zip file. I have been able to get the attachment. here is part of the code:

 Iterator<?> i = soapResponse.getAttachments();
 Object obj = null;
 AttachmentPart att = (AttachmentPart) i.next();

So, I have the zip file as a type "AttachmentPart" however I could also do:

byte[] arr1 = att.getRawContentBytes();

which would give me the array of bytes containing the zip file.

I could also do

Object obj = att.getContent()

So, I can get the zip files in different formats/types. The zip files contains two .csv files and I have to do different stuff to those files. To make my question simpler, all I am looking to do for now is to get the two .csv files and print its content to the console.

I want to do everything in memory. I don't want to put the content of the zip files on disk.

How can I unzip the attachment and print the content?

mchl45
  • 29
  • 4
  • 3
    Try using ```att.getRawContent()``` which returns an ```InputStream``` which should be able to be passed to any unzip function. – theawesometrey Jul 08 '19 at 22:33
  • @TreyGraham yes I can use getRawContent but I do not have an unzip function. That is also another thing I'm asking help with – mchl45 Jul 08 '19 at 22:36
  • 1
    After a quick google search it looks like you could use the functionality in the ```java.util.zip``` package. The link to the example I found is https://www.baeldung.com/java-compress-and-uncompress. Instead of writing the ```OutputStream``` to a file like in the example, you could redirect it to standard out to display contents. – theawesometrey Jul 08 '19 at 22:40

1 Answers1

2

If you grab the att.getRawContent() from the AttachmentPart object, you can pass it to the built in ZipInputStream to read the contents of the zip file. You can then write the bytes read from the ZipInputStream directly to System.out to view the contents on the console.

Below is an example that should read the zip contents and then write the entry name followed by the entry contents to standard out, assuming you pass it the AttachmentPart that contains the zip file. It will also filter out any entries that are directories so that they are not printed.

public static void printAttachmentPartZip(AttachmentPart att) throws IOException, SOAPException {
    try (ZipInputStream zis = new ZipInputStream(att.getRawContent())) {
        byte[] buffer = new byte[1024];
        for (ZipEntry zipEntry = zis.getNextEntry(); zipEntry != null; zipEntry = zis.getNextEntry()) {
            if (zipEntry.isDirectory()) {
                continue;
            }
            System.out.println(zipEntry.getName());
            for (int len = zis.read(buffer); len > 0; len = zis.read(buffer)) {
                System.out.write(buffer, 0, len);
            }
        }
    }
}
theawesometrey
  • 349
  • 2
  • 10
  • thank. This code does what I want. However I'm interested in understanding how the second for loop works (int len = zis.read(buffer);len > 0......). What does each iteration of that for loop do? Print one character per iteration? – mchl45 Jul 09 '19 at 14:52
  • @mchl45 it prints up to 1024 bytes per iteration, where I believe 1-2 bytes is equivalent to 1 character depending on the encoding. If you want it into a string you could write the output instead of to standard out, to a ```ByteArrayOutputStream``` and then call ```toString``` on it after the inner for loop. An example is in the post https://stackoverflow.com/questions/309424/how-do-i-read-convert-an-inputstream-into-a-string-in-java. – theawesometrey Jul 10 '19 at 00:07
  • do you know how I could print the file line by line? – mchl45 Jul 10 '19 at 21:03
  • @mchl45 you can wrap the ```ZipInputStream``` with an ```InputStreamReader``` followed by a ```BufferedReader``` like so ```BufferedReader br = new BufferedReader(new InputStreamReader(zis));```. Then you can read line by line like you would with any ```BufferedReader```. – theawesometrey Jul 11 '19 at 00:28