Search code examples
javajava-iozip4j

How to parse file inside a zip without writing to disk - java


I have a password protected zip file [in the form of a base64 encoded data and the name of the zip file] which contains a single xml. I wish to parse that xml without writing anything to disk. What is the way to do this in Zip4j? Following is what I tried.

        String docTitle = request.getDocTitle();
        byte[] decodedFileData = Base64.getDecoder().decode(request.getBase64Data());

        InputStream inputStream = new ByteArrayInputStream(decodedFileData);
        try (ZipInputStream zipInputStream = new ZipInputStream(inputStream, password)) {

            while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
                String fileTitle = localFileHeader.getFileName();
                File extractedFile = new File(fileTitle);
                try (InputStream individualFileInputStream =  org.apache.commons.io.FileUtils.openInputStream(extractedFile)) {
                    // Call parser
                    parser.parse(localFileHeader.getFileName(),
                            individualFileInputStream));
                } catch (IOException e) {
                    // Handle IOException
                }
            }
        } catch (IOException e) {
            // Handle IOException
        }

Which is throwing me java.io.FileNotFoundException: File 'xyz.xml' does not exist at line FileUtils.openInputStream(extractedFile). Can you please suggest me the right way to do this?


Solution

  • ZipInputStream keeps all content of a zip file. Each call of zipInputStream.getNextEntry() delivers the content of each file and moves "pointer" to the next entry (file). You also can read the file (ZipInputStream.read) before moving to the next entry.

    Your case:

            byte[] decodedFileData = Base64.getDecoder().decode(request.getBase64Data());
            InputStream inputStream = new ByteArrayInputStream(decodedFileData);
            try (ZipInputStream zipInputStream = new ZipInputStream(inputStream, password)) {
                ZipEntry zipEntry = null;
                while ((zipEntry = zipInputStream.getNextEntry()) != null) {
                    byte[] fileContent = IOUtils.toByteArray(zipInputStream);
                    parser.parse(zipEntry.getName(),
                                new ByteArrayInputStream(fileContent)));      
                }
            } catch (Exception e) {
                // Handle Exception
            }