Using java.util.zip to construct valid epub
Asked Answered
T

1

8

I built a method that recursively adds the contents of a folder to a zip document with the file extension "epub," which is basically what an epub is except for one thing:

the first document in the archive must be named "mimetype," the type must be specified application/epub+zip, and must start with a byte offset of 38. Is there a way to add the mimetype to the archive with offset 38?

The method I built nearly works. It constructs an epub which can be read by most e-readers, but it doesn't validate. EpubCheck gives this error:

mimetype contains wrong type (application/epub+zip expected)

This is an issue that does not exist in the original test epub, but shows up in the reconstructed epub. And I double checked that the contents of the unzipped/rezipped mimetype file are correct.

The method is too much to post here. But this is what I'm using to add the mimetype file to the archive:

out = new ZipOutputStream(new FileOutputStream(outFilename));

FileInputStream in = new FileInputStream(mimeTypePath);
out.putNextEntry(new ZipEntry("mimetype"));

int len;
while ((len = in.read(buf)) > 0) {
   out.write(buf, 0, len);
}

out.closeEntry();
in.close();
out.close();
Tiddly answered 15/8, 2011 at 8:4 Comment(3)
Any particular reason why you're reinventing the wheel rather than using existing libraries, such as siegmann.nl/epublib? Even if you don't end up using it, reading the source will tell you how it's properly done.Tottering
can you provide the procedure for creating epub zip in brief or suggest some tutorial?Jaquenette
@GAMA, your question might be better suited to a new topic here on stackoverflow. If you post the question, you'll most likely get the info you need. Depending on what you're attempting, I may have the answer you need. But it needs to be in a new topic.Tiddly
P
10

According to Wikipedia's description of the Open Container Format, the mimetype file should be the first entry in the ZIP file, and it should be uncompressed.

Based on your sample code alone, it's not clear whether you're specifying that the mimetype file should be STORED (uncompressed).

The following seems to get me past the "mimetype contains wrong type" error:

private void writeMimeType(ZipOutputStream zip) throws IOException {
    byte[] content = "application/epub+zip".getBytes("UTF-8");
    ZipEntry entry = new ZipEntry("mimetype");
    entry.setMethod(ZipEntry.STORED);
    entry.setSize(20);
    entry.setCompressedSize(20);
    entry.setCrc(0x2CAB616F); // pre-computed
    zip.putNextEntry(entry);
    zip.write(content);
    zip.closeEntry();
}

Confirmed: removing the setMethod(), setSize(), setCompressedSize() and setCrc() lines yields the "mimetype contains wrong type" error from epubcheck.

Phung answered 15/8, 2011 at 8:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.