我使用.NET 4.5 System.IO.Compression.ZipArchive编写了一些生成ePub存档的代码。我需要它成为可移植类库(PCL)的一部分,因此使用.NET fx。
的子集我遇到了包含魔术'application / epub + zip'的mimetype文件的问题。阅读完规范后,我首先添加该文件而不进行压缩。
尽管如此,生成的ePub存档不符合规范。规范要求mimetype文件的内容应从位置38开始。我的位置从47开始。
ZipArchive本身没有任何参数,ZipArchiveEntry只能通过压缩模式进行参数化。我有点困惑,因为我认为Zip文件有多种,我不明白是什么影响了这种特定的行为。
作为参考,以下是ePub示例(工作原理)的第一部分:
这是我的:
答案 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);
}
}*/