Java-код для сборки epub не работает - PullRequest
2 голосов
/ 15 ноября 2011

Я создал класс Java для чтения текстового файла и преобразования в формат EPUB. Мой код может генерировать необходимые файлы в объект ZipOutputStream (java.util.zip).Созданный файл zio содержит следующие файлы:

  1. index.html
  2. mimetype
  3. content.opf
  4. toc.ncx
  5. META-INF / container.xml

Но когда я пытался загрузить файл epub, это не работало.Онлайновая проверка epub (http://threepress.org/document/epub-validate/) выдает ошибку, что файл «META-INF / container.xml» не найден, однако странно то, что я могу правильно распаковать zip-архив и все будет готово, если я заново создаю извлечение в zip-файлс помощью утилиты windows winzip, которая работает в epub! Вот фрагмент кода, используемый для создания файла container.xml

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();
}

}

Я попытался изменить UTF-8 на значение по умолчанию, но безрезультатно

Спасибо зазаранее

Ответы [ 2 ]

1 голос
/ 15 ноября 2011

Если я изменю

ZipEntry entry = new ZipEntry(metaFolder+File.separator+containerFile);

до

final ZipEntry entry = new ZipEntry(metaFolder + "/" + containerFile);

у меня работает (на винде). EpubCheck по-прежнему показывает некоторые (новые) ошибки, вы также должны их проверить.


Убедитесь, что вы поместили записи в zip / epub в следующем порядке:

  • mimetype
  • META-INF/*
  • все остальное

Я могу найти некоторые различия между вашим оригинальным epub и перепакованной версией:

# 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

Я бы попробовал поместить в папку zip файл META-INF.

EpubCheck также сообщает об ошибке:

ERROR: android.epub: Required META-INF/container.xml resource is missing

Если запись META-INF не помогает, проверьте источник EpubCheck, возможно, это может помочь.

0 голосов
/ 08 ноября 2013

Я знаю, что это было давно, но на всякий случай, если кто-нибудь снова столкнется с этой проблемой, я думаю, что проблема может быть в исходном коде метода createMeta().

    zip.write("<rootfile full-path=\"content.opf\" media-type=\"application/oebps-package+xml\"/>\r\n".getBytes("UTF-8"));

не должно ли быть так?

    zip.write("<rootfile full-path=\"OEBPS/content.opf\" media-type=\"application/oebps-package+xml\"/>\r\n".getBytes("UTF-8"));
...