Nevron Open Vision Documentation
Zip Compression

The zip file format is widely used because of its speed and good compression ratio. That is why in many scenarios applications need the ability to compress and decompress zip archives. Nevron Open Vision provides full support for compressing and decompressing zip archives, including decompressing only individual files from an archive which leads to better performance when only specific files need to be extracted from the archive.

Zip Items

Both ZIP compression and decompression of NOV work with ZIP items. A ZIP item is basically a named stream, which the NOV ZIP engine can compress/decompress. A ZIP item exposes the following properties:

The following ZIP item properties are only used when compressing ZIP items:

Compressing Files

To compress a set of streams to a ZIP stream you should call the NCompression.CompressZip method, providing an implementation of the INZipCompressor interface as a parameter. You can also pass a password to the NCompression.CompressZip method in case you want to create a password protected ZIP archive. The INZipCompressor implementation should implement the following methods:

NOV includes the following implementations of the INZipCompressor interface:

A common task is to compress all or some of the files in a given directory and possibly it's subdirectories. If that's what you want to do, NOV provides and implementation of the INZipCompressor interface that you can use directly - the NDirectoryZipCompressor class. You can use its properties to configure the files that should be compressed using a file mask and whether to scan only the top directory all of the subdirectories. You can also override its ShouldCompressFile method if you want to further exclude some of the files from compressing.

The following example demonstrates how to compress all files in a given directory and its subdirectories:

Compress all files in a directory and its subdirectories
Copy Code
INZipCompressor zipCompressor = new NDirectoryZipCompressor(sourcePath);
using (Stream zipStream = NFile.Create(targetFileName))
{
    NCompression.CompressZip(zipStream, ENCompressionLevel.BestCompression, zipCompressor);
}

The example bellow shows how to compress all text files (*.txt) in a given directory only without scanning its subdirectories:

Compress all text files in a directory
Copy Code
INZipCompressor zipCompressor = new NDirectoryZipCompressor(sourcePath, "*.txt", ENDirectoryScanMode.TopDirectory);
using (Stream zipStream = NFile.Create(targetFileName))
{
    NCompression.CompressZip(zipStream, ENCompressionLevel.BestCompression, zipCompressor);
}
Compressing Objects

If instead of compressing files, you want to compress objects or memory streams, you should implement the INZipCompressor interface and use it instead of the NDirectoryZipCompressor implementation.

The following INZipCompressor implementation demonstrates how to compress an array of dates, each date to a different zip item:

Compress an array of objects
Copy Code
public class CustomZipCompressor : INZipCompressor
{
    public CustomZipCompressor(DateTime[] dates)
    {
        m_Dates = dates;
    }

    public INIterable<NZipItem> GetItemsToCompress()
    {
        NList<NZipItem> items = new NList<NZipItem>(m_Dates.Length);
        for (int i = 0; i < m_Dates.Length; i++)
        {
            // Serialize the current date to a memory stream
            byte[] data = NBitConverter.GetBytesLE(m_Dates[i].Ticks);
            MemoryStream stream = new MemoryStream(data);
            // Create a zip item and add it to the list
            NZipItem zipItem = new NZipItem("Date_" + i.ToString(), stream);
            items.Add(zipItem);
        }
        return items;
    }
    public void OnItemCompressed(NZipItem item)
    {
        // Dispose the item's stream
        item.Stream.Dispose();
    }

    private DateTime[] m_Dates;
}

If you want to compress one or more NOV nodes, i.e. objects subclass of NNode, you can directly use the NNodeZipCompressor class:

Compressing NNode instances
Copy Code
NNodesZipCompressor zipCompressor = new NNodesZipCompressor(zipFileName, ENPersistencyFormat.Binary, myNode);
NCompression.CompressZip(stream, ENCompressionLevel.BestCompression, zipCompressor);
Decompression

To decompress a ZIP archive to a set of items you should call the NCompression.DecompressZip method with an implementation of the INZipDecompressor interface as a parameter. The INZipDecompressor implementation should specify which files from the ZIP archive should be decompressed and process the decompressed streams. You can also pass a password if you know that the ZIP archive is password protected. The OnItemDecompressed method is called each time a zip item has been decompressed and you can use the Name and Stream properties of the passed zip item to obtain its name or content respectively.

The example below shows an implementation of the INZipDecompressor interface that decompresses all text files (*.txt) from a ZIP archive:

INZipDecompressor Implementation
Copy Code
internal class NZipDecompressor : INZipDecompressor
{
    public NZipDecompressor()
    {
    }

    public bool Filter(NZipItem item)
    {
        // Filter only text files
        return item.Name.EndsWith(".txt", StringComparison.OrdinalIgnoreCase);
    }

    public void OnItemDecompressed(NZipItem item)
    {
        // Process the zip item here    
    }
}

To decompress the files simply call the NCompression.DecompressZip static method passing an instance of the NZipDecompressor class presented above:

ZIP Decompression
Copy Code
NZipDecompressor zipDecompressor = new NZipDecompressor();
NZipCompression.DecompressZip(zipStream, zipDecompressor);
See Also
Send Feedback