Dealing with strict EPUB field length requirements and ZipOutputStream

Mar 30, 2012 at 4:34 PM
Edited Mar 30, 2012 at 4:35 PM

I'm having an issue similar to this thread: http://dotnetzip.codeplex.com/discussions/209184

I am using ZipOutputStream to create an epub file, because I'm assembling it from various in-memory and on-disk sources. Works well, and it does open in some readers. However, when I validate it with epubcheck, I get this message:

 

ERROR: filename.epub: Extra field length for first filename must be 0, but was 20 !

 

I create a new ZipEntry with path "mimetype", set IsUnicodeText to false, set ExternalFileAttributes to 0, set Flags to 0, set ExtraData to a blank array or null, set CompressionMethod to Stored and write "application/epub+zip" to the stream.

When I look at the file with a hex editor, I do see 20 extra bytes after "mimetype".

 

01 00 10 00 2a 00 00 00 00 00 00 00 2a 00 00 00 00 00 00 00

 

Where are those bytes coming from? How do I get rid of them? I don't know enough about the ZIP format or this library to attempt to figure out what they actually are, I assumed they were extra fields as in the linked thread.

 

(My code is in F# which may look a bit strange to you, but here's the sample...)

 

  use outStream = IO.WriteStream options.OutputPath
  use zip = new Zip.ZipOutputStream(outStream)

  let AddLiteralHelper (compress:bool) (path:string) (content:string) =
    let entry = new Zip.ZipEntry(path)
    entry.IsUnicodeText <- false
    entry.ExternalFileAttributes <- 0
    entry.Flags <- 0
    entry.ExtraData <- Array.empty
    if not compress then
      entry.CompressionMethod <- Zip.CompressionMethod.Stored
    zip.PutNextEntry(entry)
    let stuff = IO.StringStream content
    stuff.CopyTo zip

  // Add a file with `content` at `path`
  let AddLiteral = AddLiteralHelper true
  let AddLiteralUncompressed = AddLiteralHelper false


  // Configure the epub metadata

  AddLiteralUncompressed "mimetype" "application/epub+zip"

  AddLiteral "META-INF/container.xml"
    @"some xml goes here... snipped for brevity"

 

Apr 4, 2012 at 9:51 PM

For anyone who Googles this way or sees this post later, I just switched zip libraries to DotNetZip, which supports the setting

  ZipFile.EmitTimesInWindowsFormatWhenSaving

Which, when turned off, works fine for EPUB.