Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating an Epub file with a Zip library

Tags:

c#

zip

epub

HI All,

I am trying to zip up an Epub file i have made using c#

Things I have tried

  • Dot Net Zip http://dotnetzip.codeplex.com/
  • - DotNetZip works but epubcheck fails the resulting file (**see edit below)
  • ZipStorer zipstorer.codeplex.com
  • - creates an epub file that passes validation but the file won't open in Adobe Digital Editions
  • 7 zip
  • - I have not tried this using c# but when i zip the file using there interface it tells me that the mimetype file name has a length of 9 and it should be 8

In all cases the mimetype file is the first file added to the archive and is not compressed

The Epub validator that I'am using is epubcheck http://code.google.com/p/epubcheck/

if anyone has succesfully zipped an epub file with one of these libraries please let me know how or if anyone has zipped an epub file successfully with any other open source zipping api that would also work.


EDIT

DotNetZip works, see accepted answer below.

like image 572
claybo.the.invincible Avatar asked May 05 '11 13:05

claybo.the.invincible


1 Answers

If you need to control the order of the entries in the ZIP file, you can use DotNetZip and the ZipOutputStream.

You said you tried DotNetZip and it (the epub validator) gave you an error complaining about the mime type thing. This is probably because you used the ZipFile type within DotNetZip. If you use ZipOutputStream, you can control the ordering of the zip entries, which is apparently important for epub (I don't know the format, just surmising).


EDIT

I just checked, and the epub page on Wikipedia describes how you need to format the .epub file. It says that the mimetype file must contain specific text, must be uncompressed and unencrypted, and must appear as the first file in the ZIP archive.

Using ZipOutputStream, you would do this by setting CompressionLevel = None on that particular ZipEntry - that value is not the default.

Here's some sample code:

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

See the documentation for ZipOutputStream here.

like image 154
Cheeso Avatar answered Oct 03 '22 19:10

Cheeso