tags:

views:

85

answers:

1

Use Case

I need to package up our kml which is in a String into a kmz response for a network link in Google Earth. I would like to also wrap up icons and such while I'm at it.

Problem

Using the implementation below I receive errors from both WinZip and Google Earth that the archive is corrupted or that the file cannot be opened respectively. The part that deviates from other examples I'd built this from are the lines where the string is added:

ZipEntry kmlZipEntry = new ZipEntry("doc.kml");
out.putNextEntry(kmlZipEntry);
out.write(kml.getBytes("UTF-8"));

Please point me in the right direction to correctly write the string so that it is in doc.xml in the resulting kmz file. I know how to write the string to a temporary file, but I would very much like to keep the operation in memory for understandability and efficiency.

    private static final int BUFFER = 2048;
    private static void kmz(OutputStream os, String kml)
    {
        try{
            BufferedInputStream origin = null;
            ZipOutputStream out = new ZipOutputStream(os);
            out.setMethod(ZipOutputStream.DEFLATED);
            byte data[] = new byte[BUFFER];
            File f = new File("./icons"); //folder containing icons and such
            String files[] = f.list();

            if(files != null)
            {
                for (String file: files) {
                    LOGGER.info("Adding to KMZ: "+ file);
                    FileInputStream fi = new FileInputStream(file);
                    origin = new BufferedInputStream(fi, BUFFER);
                    ZipEntry entry = new ZipEntry(file);
                    out.putNextEntry(entry);
                    int count;
                    while((count = origin.read(data, 0, BUFFER)) != -1) {
                        out.write(data, 0, count);
                    }
                    origin.close();
                }
            }
            ZipEntry kmlZipEntry = new ZipEntry("doc.kml");
            out.putNextEntry(kmlZipEntry);
            out.write(kml.getBytes("UTF-8"));
        }
        catch(Exception e)
        {
            LOGGER.error("Problem creating kmz file", e);
        }
    }

Bonus points for showing me how to put the supplementary files from the icons folder into a similar folder within the archive as opposed to at the same layer as the doc.kml.

Update Even when saving the string to a temp file the errors occur. Ugh.

Use Case Note The use case is for use in a web app, but the code to get the list of files won't work there. For details see how-to-access-local-files-on-server-in-jboss-application

+1  A: 

You forgot to call close() on ZipOutputStream. Best place to call it is the finally block of the try block where it's been created.


Update: To create a folder, just prepend its name in the entry name.

ZipEntry entry = new ZipEntry("icons/" + file);
BalusC
Cool, that worked! You wouldn't by chance no how to include a directory structure would you? I'd like the files in the `for` loop from the `icons` folder in the directory to be in a `icons` folder in the kmz/zip structure.
Adam
See answer update.
BalusC