Creating compatible Zip file from Java to .NET and SilverLight 2B1

In my SilverLight project needed to generated dynamically a JSON file from Java to SL. The generated JSON are usually around 1MB. I decided to decrease file size I used zip compression. In SL to handle compressed content we can use StreamResourceInfo, it supports zip as well. Unfortunatelly zip files created by java not handled properly by SL. I do lot of research (I lost 5 hours in my life) to examine what’s the problem with those zip files.

The problem is that java creates zip files on the fly, so it is like a stream (ZipOutputStream). In this case can’t determine the compressed content size and crc, when need to write ZipEntry info. After compression, java adds extended local header to zip file, which contains compressed size and crc as well.

But if we know the compressed size and crc and we set it to ZipEntry and compress it again ,SL will handle it properly.

You can find example for StreamResourceInfo usage at http://msdn.microsoft.com/en-us/library/cc190632(VS.95).aspx.

Java usage:

import hu.onlyonce.common.iop.zip.ZipUtil;

import java.io.FileOutputStream;
import java.io.OutputStream;

String json = "…";

final OutputStream baos = ZipUtil.create(new FileOutputStream("iop.zip"),
                                         json.getBytes(),
                                         "content.json",
                                         true,
                                         9);
baos.close();

ZipUtil class:

package hu.onlyonce.common.iop.zip;

import hu.onlyonce.common.stream.NullOutputStream;

import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public final class ZipUtil
{

/**
* Creating the .NET and SilverLight compatible zip file.
*/
public static OutputStream create(final OutputStream outputStream,
                       final byte[] content,
                       final String fileName,
                       final boolean needCompress,
                       final int compressionLevel ) throws IOException {
    final ZipEntry zipEntry = new ZipEntry(fileName);
    if (needCompress) {
        // Compress to null, to determine compressed size and crc
        final NullOutputStream baos = new NullOutputStream();
        final ZipOutputStream zipOut = new ZipOutputStream(baos);
        zipOut.setMethod(needCompress ? ZipOutputStream.DEFLATED : ZipOutputStream.STORED);
        zipOut.setLevel(compressionLevel);
        zipOut.putNextEntry(zipEntry);
        zipOut.write(content);
        zipOut.closeEntry();
        zipOut.finish();
        zipOut.close();
    } else {
        // No compress, just store
        final CRC32 crc = new CRC32();
        crc.update(content);
        zipEntry.setCrc(crc.getValue());
        zipEntry.setCompressedSize(content.length);
        zipEntry.setSize(content.length);
    }

    // Recompress to real stream
    final ZipOutputStream zipOut = new ZipOutputStream(outputStream);
    zipOut.setMethod(needCompress ? ZipOutputStream.DEFLATED : ZipOutputStream.STORED);
    zipOut.setLevel(compressionLevel);
    zipOut.putNextEntry(zipEntry);
    zipOut.write(content);
    zipOut.closeEntry();
    zipOut.finish();
    zipOut.close();

    return outputStream;
}

}

NullOutputStream class:

package hu.onlyonce.common.stream;

import java.io.OutputStream;

public class NullOutputStream
extends
OutputStream
{
    public NullOutputStream()
    {
        super();
    }

    @Override
    public void write(final int b)
    {
        // DO NOTHING
    }

}

Advertisements
Kategória: Silverlight | Közvetlen link a könyvjelzőhöz.

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s