0

EDIT: The error was not in this code. The download on the front-end was erroneous. The zip on the server was fine but downloading it via js didn't work.

I'm writing two xml files into a zip file. I can't open the resulting file (error: no file and no folder).

Tuple is a class that contains two Strings (A and B), my xml content. I first tried this without closeEntry and without setSize, the result is the same.

Any ideas? How can I debug this?

private static byte[] createArchive(final Tuple<String, String> body) throws IOException {

    try (final ByteArrayOutputStream bos = new ByteArrayOutputStream();
         final ZipOutputStream zos = new ZipOutputStream(bos)) {

        final ZipEntry firstEntry = new ZipEntry("first.xml");
        firstEntry.setSize(body.getA().getBytes().length);
        zos.putNextEntry(firstEntry);
        zos.write(body.getA().getBytes());
        zos.closeEntry();

        final ZipEntry secondEntry = new ZipEntry("second.xml");
        secondEntry.setSize(body.getB().getBytes().length);
        zos.putNextEntry(secondEntry);
        zos.write(body.getB().getBytes());
        zos.closeEntry();

        zos.close();

        return bos.toByteArray();
    }
}
lisa p.
  • 2,138
  • 21
  • 36
  • 2
    Where is the code of writing your `OutputStream` to File? – user2004685 Mar 30 '16 at 10:29
  • 2
    Aside from anything else, you're calling `String.getBytes()` without specifying the encoding. Don't do that - *always* specify the encoding. You're also calling `getBytes()` multiple times - once to get the length, and then again to write them. I'd call it once per entry, saving the result in a `byte[]`. You might want to extract that logic to a method, `writeStringAsZipEntry` or something similar... – Jon Skeet Mar 30 '16 at 10:29
  • The writing is done by Apache Camel. This works with other files so it's not included here. The getBytes call is still used twice because I didn't specify the size first. Is that even necessary? – lisa p. Mar 30 '16 at 10:34
  • 2
    Running your code and writing the bytes to a file, I get a zip file with two entries and the correct content. – TenPlusFive Mar 30 '16 at 11:19
  • Thanks for trying this. No idea why my file doesn't work. The error must be somewhere else. – lisa p. Mar 30 '16 at 11:24
  • Oh damn, I found the error. The zip is perfectly fine and the export as well! But providing the file for download on the frontend messes it up. The file on the server is fine, download via client fails. Thanks for your help! – lisa p. Mar 30 '16 at 11:29
  • Since the problem was somewhere else, this question is unlikely to be of much use for future readers. I've voted to close it as *not reproducible*. Although, it needs 4 further close votes. You may delete it yourself now. – Artjom B. Mar 30 '16 at 11:34

1 Answers1

0

I believe the error is not in this method. The following snippet based on your posted code creates a valid ZIP archive.

try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ZipOutputStream zos = new ZipOutputStream(bos)) {

    byte[] fileA = Files.readAllBytes(Paths.get("/tmp/fileA.xml"));
    byte[] fileB = Files.readAllBytes(Paths.get("/tmp/fileB.xml"));
    ZipEntry firstEntry = new ZipEntry("first.xml");
    firstEntry.setSize(fileA.length);
    zos.putNextEntry(firstEntry);
    zos.write(fileA);
    zos.closeEntry();

    ZipEntry secondEntry = new ZipEntry("second.xml");
    secondEntry.setSize(fileB.length);
    zos.putNextEntry(secondEntry);
    zos.write(fileB);
    zos.closeEntry();
    zos.close();

    Files.write(Paths.get("/tmp/files.zip"), bos.toByteArray());
}

check the archive

jar vtf /tmp/files.zip
     5 Wed Mar 30 13:15:02 CEST 2016 first.xml
     5 Wed Mar 30 13:15:02 CEST 2016 second.xml

As Jon Skeet mentioned it's most probably related to body.getA(). If this method returns a String you should specify the encoding to be sure the file content is not garbled.

Community
  • 1
  • 1
SubOptimal
  • 22,518
  • 3
  • 53
  • 69