Web developers wiki ASP.NET Sitecore Sharepoint Kentico by Evident Interactive

ZipPackage versus GzipStream

Modified: 2010/12/08 16:12 by jim - Categorized as: 2010, ASP.NET, Csharp, Visual Studio, Windows
Old, native .NET object GZipStream inside System.IO.Compression has the behaviour that resulting compressed files are of type gz (what's in a name). The resulting files are not usable by the Windows Explorer, i.e. double clicking them in the explorer results in an error: "Windows cannot open the folder. The Compressed Folder is invalid."

Using dedicated programs like WinRar, 7Zip and others is a way to work around this problem. This is not always a viable sollution since company systems administrators do not allow the installation of random programs and time consuming procedures must be followed before the programmes can be installed.

Without using free libraries like SharpZipLib but sticking with the .NET framework, we found out Microsoft has implemented Packaging since the 3.0 version. The contents of a package can be compressed in a way the Windows Explorer can handle them.

Using the System.IO.Packinging namespace involves referencing the WindowsBase.dll. The following sample method takes a byte Array, compresses it and uploads it using FTPS
// byteArray originates from SQL database varbinary(max)
// docName contains the name of the document
private void UploadByteArrayDocument(byte[] byteArray, string docName)
{
    FileInfo fileInf = new FileInfo(docName);
// in the reqFTP you set the name of the file on the file system
    FtpWebRequest reqFTP = (FtpWebRequest)WebRequest.Create(
                               new Uri("ftp://" + ftpServerIP + "/" + fileInf.Name.Replace
                                        (fileInf.Extension,".zip")));
// ... omitting setting of properties for the FtpWebRequest ...
// The buffer size is set to 2kb
    int buffLength = 2048;
    byte[] buff = new byte[buffLength];
    int contentLen;

// document bytes into MemoryStream
    MemoryStream memStream = new MemoryStream(byteArray);
// declare the stream that will contain the compressed bytes
    MemoryStream zippedStream = new MemoryStream();

// create the package using the zippedStream object 
    Package package = ZipPackage.Open(zippedStream, FileMode.Create);

// create a relative URI to define the name of the file that will be compressed inside the package
    Uri uri = PackUriHelper.CreatePartUri(new Uri(fileInf.Name, UriKind.Relative));
    PackagePart packagePart = package.CreatePart(uri,"",CompressionOption.Maximum);

// copy the document byteArray stream into the packagepart.
    CopyStream(memStream, packagePart.GetStream());

// close the package
    package.Close();

// reset the stream that contains the package.
    zippedStream.Position = 0;

// create a stream that will be used by the FTPWebRequest object 
    Stream strm = reqFTP.GetRequestStream();

// read the stream containing the package into the buffer
    contentLen = zippedStream.Read(buff, 0, buffLength);
    while (contentLen != 0)
    {
     // Write the buffer to the FTP Upload Stream
        strm.Write(buff, 0, contentLen);
        contentLen = zippedStream.Read(buff, 0, buffLength);
    }
// close all the streams in the right order. I prefer this to closing the 'top' stream to implicitely
// close all the underlying streams. 
    zippedStream.Close();
    memStream.Close();
    strm.Close();

}

 © Evident Interactive BV