Создание файла Epub с библиотекой Zip - PullRequest
9 голосов
/ 05 мая 2011

HI All,

Я пытаюсь заархивировать файл Epub, который я сделал с помощью c #

Вещи, которые я пробовал

Во всех случаях файл mimetype является первым файлом, добавленным в архив, и не сжимается

Я использую валидатор Epub - epubcheck http://code.google.com/p/epubcheck/

если кто-нибудь успешно заархивировал файл epub с одной из этих библиотек, пожалуйста, дайте мне знать, как или если кто-то успешно заархивировал файл epub с любым другим открытым zip api-файлом, который также будет работать.


EDIT

DotNetZip работает, см. Принятый ответ ниже.

Ответы [ 3 ]

12 голосов
/ 05 мая 2011

Если вам нужно контролировать порядок записей в файле ZIP, вы можете использовать DotNetZip и ZipOutputStream.

Вы сказали, что пробовали DotNetZip, и он (валидатор epub) выдал ошибку, сообщающую о типе mime. Вероятно, это связано с тем, что вы использовали тип ZipFile в DotNetZip. Если вы используете ZipOutputStream, вы можете управлять порядком записей zip, что, по-видимому, важно для epub (я не знаю формат, просто предположив).


РЕДАКТИРОВАТЬ

Я только что проверил, и на странице epub в Википедии описано, как вам нужно отформатировать файл .epub. В нем говорится, что файл mimetype должен содержать определенный текст, должен быть несжатым и незашифрованным и должен отображаться как первый файл в ZIP-архиве.

Используя ZipOutputStream, вы могли бы сделать это, установив CompressionLevel = None для этого конкретного ZipEntry - это значение не является значением по умолчанию.

Вот пример кода:

private void Zipup()
{
    string _outputFileName = "Fargle.epub";
    using (FileStream fs = File.Open(_outputFileName, FileMode.Create, FileAccess.ReadWrite ))
    {
        using (var output= new ZipOutputStream(fs))
        {
            var e = output.PutNextEntry("mimetype");
            e.CompressionLevel = CompressionLevel.None;

            byte[] buffer= System.Text.Encoding.ASCII.GetBytes("application/epub+zip");
            output.Write(buffer,0,buffer.Length);

            output.PutNextEntry("META-INF/container.xml");
            WriteExistingFile(output, "META-INF/container.xml");
            output.PutNextEntry("OPS/");  // another directory
            output.PutNextEntry("OPS/whatever.xhtml");
            WriteExistingFile(output, "OPS/whatever.xhtml");
            // ...
        }
    }
}

private void WriteExistingFile(Stream output, string filename)
{
    using (FileStream fs = File.Open(fileName, FileMode.Read))
    {
        int n = -1;
        byte[] buffer = new byte[2048];
        while ((n = fs.Read(buffer,0,buffer.Length)) > 0)
        {
            output.Write(buffer,0,n);
        }
    }
}

См. Документацию для ZipOutputStream здесь .

7 голосов
/ 06 сентября 2012

Почему бы не облегчить жизнь?

private void IonicZip()
{
    string sourcePath = "C:\\pulications\\";
    string fileName = "filename.epub";

    // Creating ZIP file and writing mimetype
    using (ZipOutputStream zs = new ZipOutputStream(sourcePath + fileName))
    {
        var o = zs.PutNextEntry("mimetype");
        o.CompressionLevel = CompressionLevel.None;

        byte[] mimetype = System.Text.Encoding.ASCII.GetBytes("application/epub+zip");
        zs.Write(mimetype, 0, mimetype.Length);
    }

    // Adding META-INF and OEPBS folders including files     
    using (ZipFile zip = new ZipFile(sourcePath + fileName))
    {
        zip.AddDirectory(sourcePath  + "META-INF", "META-INF");
        zip.AddDirectory(sourcePath  + "OEBPS", "OEBPS");
        zip.Save();
    }
}
0 голосов
/ 09 июня 2019

Для тех, кто, как я, ищет другие способы сделать это, я хотел бы добавить, что класс ZipStorer от Хайме Оливареса - отличная альтернатива. Вы можете скопировать код прямо в свой проект, и очень легко выбрать между «deflate» и «store».

https://github.com/jaime-olivares/zipstorer

Вот мой код для создания EPUB:

Dictionary<string, string> FilesToZip = new Dictionary<string, string>()
{
    { ConfigPath + @"mimetype",                 @"mimetype"},
    { ConfigPath + @"container.xml",            @"META-INF/container.xml" },
    { OutputFolder + Name.Output_OPF_Name,      @"OEBPS/" + Name.Output_OPF_Name},
    { OutputFolder + Name.Output_XHTML_Name,    @"OEBPS/" + Name.Output_XHTML_Name},
    { ConfigPath + @"style.css",                @"OEBPS/style.css"},
    { OutputFolder + Name.Output_NCX_Name,      @"OEBPS/" + Name.Output_NCX_Name}
};

using (ZipStorer EPUB = ZipStorer.Create(OutputFolder + "book.epub", ""))
{
    bool First = true;
    foreach (KeyValuePair<string, string> File in FilesToZip)
    {
        if (First) { EPUB.AddFile(ZipStorer.Compression.Store, File.Key, File.Value, ""); First = false; }
        else EPUB.AddFile(ZipStorer.Compression.Deflate, File.Key, File.Value, "");
    }
}

Этот код создает совершенно корректный файл EPUB. Тем не менее, если вам не нужно беспокоиться о проверке, кажется, что большинство eReaders примет EPUB с mimetype «deflate». Поэтому мой предыдущий код, использующий ZipArchive .NET, создал EPUB, которые работали в Adobe Digital Editions и PocketBook.

...