如何使用System.IO.Compression.ZipArchive创建ePub?

时间:2013-10-28 21:27:36

标签: .net zip epub ziparchive

我使用.NET 4.5 System.IO.Compression.ZipArchive编写了一些生成ePub存档的代码。我需要它成为可移植类库(PCL)的一部分,因此使用.NET fx。

的子集

我遇到了包含魔术'application / epub + zip'的mimetype文件的问题。阅读完规范后,我首先添加该文件而不进行压缩。

尽管如此,生成的ePub存档不符合规范。规范要求mimetype文件的内容应从位置38开始。我的位置从47开始。

ZipArchive本身没有任何参数,ZipArchiveEntry只能通过压缩模式进行参数化。我有点困惑,因为我认为Zip文件有多种,我不明白是什么影响了这种特定的行为。

作为参考,以下是ePub示例(工作原理)的第一部分:

enter image description here

这是我的:

enter image description here

3 个答案:

答案 0 :(得分:2)

您没有将压缩方法设置为“无压缩”。数据的字节9-10用于压缩方法,对于工作文件,它应该是00,但在你的情况下,它们被设置为8 - 'deflate'。 压缩级别不是压缩方法,将其设置为0仍然使用deflate。 你应该尝试另一个库,比如SecureBlackbox或DotNetZip。

答案 1 :(得分:0)

我确实遵循了Nickolay的建议,我使用DotNetZip创建了一个只包含mimetype文件的存档,并使用该文件作为其他epub的起点。

这种方法允许我在尊重ePub规范的同时使用ZipArchive及其异步接口。

答案 2 :(得分:0)

正如Nickolay指出的那样,正在使用“放气”方法而不是“存储”方法。对于我来说,找出解决方法非常痛苦,对于其他找到此主题的人,我使用了Jaime Olivares的ZipStorer类,通过“ store”添加了mimetype。

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

很容易将此代码添加到C#项目(不是DLL),并且很容易使用“存储”而不是“放气”添加文件。这是我这样做的代码:

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文件。但是,如果您不必担心验证,似乎大多数电子阅读器都会接受带有“ deflate”模仿类型的EPUB。因此,我以前使用.NET的ZipArchive编写的代码产生了可在Adobe Digital Editions和PocketBook中使用的EPUB。例如:

/*using (ZipArchive EPUB = ZipFile.Open(OutputFolder + Name.Output_EPUB_Name, ZipArchiveMode.Create))
{
    foreach (KeyValuePair<string, string> AddFile in AddFiles)
    {
        if (AddFile.Key.Contains("mimetype"))
        {
            EPUB.CreateEntryFromFile(AddFile.Key, AddFile.Value, CompressionLevel.NoCompression);
        }
        else EPUB.CreateEntryFromFile(AddFile.Key, AddFile.Value, CompressionLevel.Optimal);
    }
}*/