Zip file containing more than one file is sent as string. How to read the string and extract individual files in Java?

280 Views Asked by At

Our external application sends the zip file name and content as two strings in the response to an API call. I converted the string to bytearray and used zipinputstream to read the bytearray. If the zip file contains only one file, I am able to read the string and extract the zipped file contents into a separate string. Below is the code snippet I used to extract the file content.

If the zipped file contains more than one file and the entire zipped content is sent as a single string, how do I extract individual file contents into separate strings? How to identify the end of each file in the string?

byte[] data = Base64Util.decodeToByteArray(ZipString);
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ZipInputStream zin = new ZipInputStream(new BufferedInputStream(bais));
ZipEntry ze = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b =  new byte[4096];
String ZippedFileName = new String();
String ZippedFileData = new String();

try 
{
 while((ze = zin.getNextEntry()) != null)
 {
    ZippedFileName = ze.getName();
    while((zin.read(b,0,4096))!= -1)
    {
        baos.write(b,0,4096);
    }
 }
 byte[] out = baos.toByteArray();
 ZippedFileData = Base64Util.encodeToString(out);
 zin.close();
 bais.close();
 baos.close();
}

catch(Exception Ex)
{
    Ex.toString();
}
1

There are 1 best solutions below

2
g00se On

Actually I think I was presenting the base64 file in string form incorrectly. For one thing, if line feeds are present in the input, it doesn't like it. If you're working on a Unix based system, you can run the below with something like java Unzip64

"$(cat a.zip | base64 | tr -d '\n')"

The following is working fine for me

import java.util.zip.ZipInputStream;
import java.util.zip.ZipEntry;
import java.util.Base64;
import java.util.Map;
import java.util.HashMap;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

public class Unzip64 {
    public static void main(String[] args) {
        System.out.println(Unzip64.getEntriesAndContents(args[0]));
    }

    public static Map<String, String> getEntriesAndContents(String base64Zip) {
        Map<String, String> result = new HashMap<>();
        try {
            byte[] data = Base64.getDecoder().decode(base64Zip);
            ByteArrayInputStream bais = new ByteArrayInputStream(data);
            try (ZipInputStream zin = new ZipInputStream(bais)) {
                ZipEntry ze = null;
                byte[] b = new byte[4096];

                while ((ze = zin.getNextEntry()) != null) {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    int numRead = -1;
                    String entryName = ze.getName();
                    while ((numRead = zin.read(b, 0, b.length)) > -1) {
                        baos.write(b, 0, numRead);
                    }
                    String entryData = new String(baos.toByteArray());
                    result.put(entryName, entryData);
                    baos = null;
                    zin.closeEntry();
                }
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }
        return result;
    }
}

And here's a sample to run: UEsDBAoAAAgAAKdCJ1UAAAAAAAAAAAAAAAAHAAQAcm9vdC9hL/7KAABQSwMEFAAICAgAp0InVQAAAAAAAAAAAAAAAAwAAAByb290L2EvYS50eHRL5AIAUEsHCAeh6t0EAAAAAgAAAFBLAwQUAAgICACnQidVAAAAAAAAAAAAAAAADAAAAHJvb3QvYS9iLnR4dEviAgBQSwcIxPLH9gQAAAACAAAAUEsDBBQACAgIAKdCJ1UAAAAAAAAAAAAAAAAMAAAAcm9vdC9hL2MudHh0S+YCAFBLBwiFw9zvBAAAAAIAAABQSwECCgAKAAAIAACnQidVAAAAAAAAAAAAAAAABwAEAAAAAAAAAAAAAAAAAAAAcm9vdC9hL/7KAABQSwECFAAUAAgICACnQidVB6Hq3QQAAAACAAAADAAAAAAAAAAAAAAAAAApAAAAcm9vdC9hL2EudHh0UEsBAhQAFAAICAgAp0InVcTyx/YEAAAAAgAAAAwAAAAAAAAAAAAAAAAAZwAAAHJvb3QvYS9iLnR4dFBLAQIUABQACAgIAKdCJ1WFw9zvBAAAAAIAAAAMAAAAAAAAAAAAAAAAAKUAAAByb290L2EvYy50eHRQSwUGAAAAAAQABADnAAAA4wAAAAAA