Reputation: 1295
I made a java class to read a txt file and convert into EPUB format, My code is able to generated necessary files into ZipOutputStream (java.util.zip) object. Generated zio file contains following files:
But when I tried to load epub file is it unworkable. Online epub validation (http://threepress.org/document/epub-validate/) throws error that "META-INF/container.xml" file was not found, however strange thing about this is I can extract zip archive properly and everything is in place also if I recreate extract to a zip file using windows winzip utility that epub is working! Here is the piece of code used to create container.xml file
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import javax.swing.JPopupMenu.Separator;
public class ToEPub {
private String rootDir;
private static String metaFolder = "META-INF";
private static String oebpsFolder = "";// "OEBPS";
private static String containerFile = "container.xml";
private static String contentPpfFile = "content.opf";
private static String tocFile = "toc.ncx";
private static String baseFileName;
private static String baseFilePathHTML;
private static String baseFileNameHTML;
private String baseFilePath;
private ZipOutputStream zip;
private String baseFileZipPath;
public ToEPub(String fileName) throws IOException {
File file = new File(fileName);
rootDir = file.getParent();
baseFileName = file.getName();
baseFilePath = file.getPath();
baseFilePathHTML = baseFilePath + ".html";
baseFileNameHTML = baseFileName.substring(0, baseFileName
.lastIndexOf("."))
+ ".html";
baseFileZipPath = baseFilePath.substring(0, baseFilePath
.lastIndexOf("."))
+ ".epub";
zip = new ZipOutputStream(new FileOutputStream(baseFileZipPath));
}
public void start() throws IOException {
createMimeFile();
createMeta();
readConnent();
createContentList();
createTocFile();
//zip.flush();
zip.close();
/*
* Reading Creating Zip again
*/
ZipFile zfile = new ZipFile(new File(baseFileZipPath));
System.out.println(zfile.size() + " Files");
Enumeration<? extends ZipEntry> itr = zfile.entries();
while(itr.hasMoreElements()){
ZipEntry entry = itr.nextElement();
System.out.println(entry.getName()+" Size: "+entry.getCompressedSize()+"/"+entry.getSize() +" CRC: "+ entry.getCrc());
}
}
public void createMimeFile() 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();
}
public void readConnent() throws IOException {
String thisLine;
FileReader fr = new FileReader(baseFilePath);
BufferedReader bReader = new BufferedReader(fr);
String outFile = oebpsFolder + File.separator + baseFileNameHTML;
ZipEntry entry = new ZipEntry(baseFileNameHTML);
zip.putNextEntry(entry);
zip.write("<?xml version='1.0' encoding='utf-8'?>\r\n".getBytes("UTF-8"));
zip.write("<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n"
.getBytes("UTF-8"));
while ((thisLine = bReader.readLine()) != null) { // while loop
// begins here
zip.write(("<p>" + thisLine + "</p>\r\n").getBytes("UTF-8"));
} // end while
zip.write("</html>".getBytes("UTF-8"));
zip.closeEntry();
}
public void createContentList() throws IOException{
ZipEntry entry = new ZipEntry(contentPpfFile);
zip.putNextEntry(entry);
zip.write("<?xml version='1.0' encoding='utf-8'?>\r\n".getBytes("UTF-8"));
zip.write("<package xmlns=\"http://www.idpf.org/2007/opf\" version=\"2.0\" unique-identifier=\"uuid_id\">".getBytes("UTF-8"));
zip.write("<metadata xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:opf=\"http://www.idpf.org/2007/opf\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:calibre=\"http://calibre.kovidgoyal.net/2009/metadata\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\r\n".getBytes("UTF-8"));
zip.write("<dc:language>en</dc:language>\r\n".getBytes("UTF-8"));
zip.write("<dc:creator opf:role=\"aut\">Open Mobile Alliance</dc:creator>\r\n".getBytes("UTF-8"));
zip.write("<meta name=\"calibre:timestamp\" content=\"2011-11-11T15:02:14.075083+00:00\"/>\r\n".getBytes("UTF-8"));
zip.write("<dc:title>OMA Specification</dc:title>\r\n".getBytes("UTF-8"));
zip.write("<dc:contributor opf:role=\"bkp\">calibre (0.8.22) [http://calibre-ebook.com]</dc:contributor>\r\n".getBytes("UTF-8"));
zip.write("<dc:identifier id=\"uuid_id\" opf:scheme=\"uuid\">22fb9171-78bd-4bd1-89f8-7cae3a497c7c</dc:identifier>\r\n".getBytes("UTF-8"));
zip.write("<dc:subject>Template</dc:subject>\r\n".getBytes("UTF-8"));
zip.write("</metadata>\r\n".getBytes("UTF-8"));
zip.write("<manifest>\r\n".getBytes("UTF-8"));
zip.write(("<item href=\""+baseFileNameHTML+"\" id=\"id1\" media-type=\"application/xhtml+xml\"/>\r\n").getBytes("UTF-8"));
zip.write("<item href=\"toc.ncx\" media-type=\"application/x-dtbncx+xml\" id=\"ncx\"/>\r\n".getBytes("UTF-8"));
zip.write("</manifest>\r\n".getBytes("UTF-8"));
zip.write("<spine toc=\"ncx\">\r\n".getBytes("UTF-8"));
zip.write("<itemref idref=\"id1\"/>\r\n".getBytes("UTF-8"));
zip.write("</spine>\r\n".getBytes("UTF-8"));
zip.write("<guide/>\r\n".getBytes("UTF-8"));
zip.write("</package>\r\n".getBytes("UTF-8"));
zip.closeEntry();
}
public void createTocFile() throws IOException{
ZipEntry entry = new ZipEntry(tocFile);
zip.putNextEntry(entry);
zip.write("<?xml version=\"1.0\"?>\r\n".getBytes("UTF-8"));
zip.write("<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">\r\n".getBytes("UTF-8"));
zip.write("<rootfiles>".getBytes("UTF-8"));
zip.write(("<rootfile full-path=\""+contentPpfFile
+"\" media-type=\"application/oebps-package+xml\"/>\r\n").getBytes("UTF-8"));
zip.write("</rootfiles>\r\n".getBytes("UTF-8"));
zip.write("</container>".getBytes("UTF-8"));
zip.closeEntry();
}
public void createMeta() throws IOException{
ZipEntry entry = new ZipEntry(metaFolder+File.separator+containerFile);
zip.putNextEntry(entry);
zip.write("<?xml version=\"1.0\"?>\r\n".getBytes("UTF-8"));
zip.write("<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">\r\n".getBytes("UTF-8"));
zip.write("<rootfiles>\r\n".getBytes("UTF-8"));
zip.write("<rootfile full-path=\"content.opf\" media-type=\"application/oebps-package+xml\"/>\r\n".getBytes("UTF-8"));
zip.write("</rootfiles>\r\n".getBytes("UTF-8"));
zip.write("</container>\r\n".getBytes("UTF-8"));
zip.closeEntry();
}
public void createMetaInfo() throws IOException{
ZipEntry entry = new ZipEntry(metaFolder+File.separator);
zip.putNextEntry(entry);
zip.closeEntry();
}
}
I tried change UTF-8 to default but not avail
Thanks in advance
Upvotes: 2
Views: 1997
Reputation: 529
I know this was a long time ago but just in case anyone comes across this problem again, I think the problem may be in the source code of the createMeta()
method.
zip.write("<rootfile full-path=\"content.opf\" media-type=\"application/oebps-package+xml\"/>\r\n".getBytes("UTF-8"));
shouldn't it be as follows?
zip.write("<rootfile full-path=\"OEBPS/content.opf\" media-type=\"application/oebps-package+xml\"/>\r\n".getBytes("UTF-8"));
Upvotes: 0
Reputation: 28865
If I change
ZipEntry entry = new ZipEntry(metaFolder+File.separator+containerFile);
to
final ZipEntry entry = new ZipEntry(metaFolder + "/" + containerFile);
it works for me (on Windows). EpubCheck still shows some (new) errors, you should check them too.
Make sure that you put the entries into the zip
/epub
in the following order:
mimetype
META-INF/*
I can find some differences between your original epub and a repacked version:
# unzip -l android.epub
Archive: android.epub
Length Date Time Name
--------- ---------- ----- ----
20 11-17-2011 14:48 mimetype
227 11-17-2011 14:48 META-INF\container.xml
1589 11-17-2011 14:48 android.html
1076 11-17-2011 14:48 content.opf
223 11-17-2011 14:48 toc.ncx
--------- -------
3135 5 files
# unzip -l my.epub
Archive: my.epub
Length Date Time Name
--------- ---------- ----- ----
20 11-17-2011 14:48 mimetype
0 11-17-2011 11:05 META-INF/
227 11-17-2011 14:48 META-INF/container.xml
1076 11-17-2011 14:48 content.opf
223 11-17-2011 14:48 toc.ncx
1589 11-17-2011 14:48 android.html
--------- -------
3135 6 files
I'd try putting a META-INF
folder entry to the zip file.
EpubCheck also reports the error:
ERROR: android.epub: Required META-INF/container.xml resource is missing
If the META-INF
entry isn't help check the source of EpubCheck maybe it can help.
Upvotes: 1