namespace Zeta.EnterpriseLibrary.Common.IO.Compression
{
#region Using directives.
// ------------------------------------------------------------------
using System.Data;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Xml;
using ICSharpCode.SharpZipLib.Zip;
using System.Collections.Generic;
// ------------------------------------------------------------------
#endregion
/////////////////////////////////////////////////////////////////////////
/// <summary>
/// Routines for decompressing various types of data.
/// </summary>
public sealed class DecompressionHelper
{
#region Decompressing.
// ------------------------------------------------------------------
/// <summary>
/// Decompress a byte stream that was formerly compressed
/// with the CompressFolder() routine with the ZIP algorithm
/// and store it to a folder.
/// </summary>
/// <param name="input">The buffer that contains the compressed
/// stream with the files and sub folders.</param>
/// <param name="folderPath">The base path where the files and folders
/// will be stored.</param>
public static void DecompressFolder(
byte[] input,
string folderPath )
{
if ( !Directory.Exists( folderPath ) )
{
Directory.CreateDirectory( folderPath );
}
using ( var mem = new MemoryStream( input ) )
using ( var stm = new ZipInputStream( mem ) )
{
ZipEntry entry;
while ( (entry = stm.GetNextEntry()) != null )
{
// Create this stream new for each zip entry.
using ( var mem2 = new MemoryStream() )
{
var data = new byte[4096];
while ( true )
{
var size = stm.Read( data, 0, data.Length );
if ( size > 0 )
{
mem2.Write( data, 0, size );
}
else
{
break;
}
}
// --
// Finished reading, now write to file.
var filePath = Path.Combine( folderPath, entry.Name );
if ( !Directory.Exists( Path.GetDirectoryName( filePath ) ) )
{
Directory.CreateDirectory( Path.GetDirectoryName( filePath ) );
}
if ( File.Exists( filePath ) )
{
File.Delete( filePath );
}
using ( var r = new BinaryReader( mem2 ) )
using ( var fs = new FileStream(
filePath,
FileMode.CreateNew,
FileAccess.Write ) )
using ( var w = new BinaryWriter( fs ) )
{
var buf = new byte[mem2.Length];
mem2.Seek( 0, SeekOrigin.Begin );
r.Read( buf, 0, (int)mem2.Length );
w.Write( buf );
}
}
}
}
}
/// <summary>
/// Decompress a byte stream that was formerly compressed
/// with the CompressFiles() routine with the ZIP algorithm
/// and store it to a file.
/// </summary>
/// <param name="input">The buffer that contains the compressed
/// stream with the files.</param>
/// <param name="folderPath">The base path where the files will be
/// stored.</param>
public static void DecompressFiles(
byte[] input,
string folderPath )
{
if ( !Directory.Exists( folderPath ) )
{
Directory.CreateDirectory( folderPath );
}
using ( var mem = new MemoryStream( input ) )
using ( var stm = new ZipInputStream( mem ) )
{
ZipEntry entry;
while ( (entry = stm.GetNextEntry()) != null )
{
// Make this stream new for each zip entry.
using ( var mem2 = new MemoryStream() )
{
var data = new byte[4096];
while ( true )
{
var size = stm.Read( data, 0, data.Length );
if ( size > 0 )
{
mem2.Write( data, 0, size );
}
else
{
break;
}
}
// --
// Finished reading, now write to file.
var filePath = Path.Combine( folderPath, entry.Name );
if ( !Directory.Exists( Path.GetDirectoryName( filePath ) ) )
{
Directory.CreateDirectory( Path.GetDirectoryName( filePath ) );
}
if ( File.Exists( filePath ) )
{
File.Delete( filePath );
}
using ( var r = new BinaryReader( mem2 ) )
using ( var fs = new FileStream(
filePath,
FileMode.CreateNew,
FileAccess.Write ) )
using ( var w = new BinaryWriter( fs ) )
{
var buf = new byte[mem2.Length];
mem2.Seek( 0, SeekOrigin.Begin );
r.Read( buf, 0, (int)mem2.Length );
w.Write( buf );
}
}
}
}
}
/// <summary>
/// Decompress a byte stream that was formerly compressed
/// with the ZIP algorithm.
/// </summary>
/// <param name="input">The buffer that contains the compressed
/// stream with the items.</param>
/// <returns>Returns the decompressed item(s).</returns>
public static DecompressedItemInfo[] DecompressItems(
byte[] input )
{
if ( input == null || input.Length <= 0 )
{
return null;
}
else
{
var result = new List<DecompressedItemInfo>();
using ( var mem = new MemoryStream( input ) )
using ( var stm = new ZipInputStream( mem ) )
{
ZipEntry entry;
while ( (entry = stm.GetNextEntry()) != null )
{
// Make this stream new for each zip entry.
using ( var mem2 = new MemoryStream() )
{
var data = new byte[4096];
while ( true )
{
var size = stm.Read( data, 0, data.Length );
if ( size > 0 )
{
mem2.Write( data, 0, size );
}
else
{
break;
}
}
// --
// Finished reading, now write to memory.
using ( var r = new BinaryReader( mem2 ) )
{
var c = new byte[mem2.Length];
mem2.Seek( 0, SeekOrigin.Begin );
r.Read( c, 0, (int)mem2.Length );
var info = new DecompressedItemInfo(
c,
entry.Name );
result.Add( info );
}
}
}
}
// --
if ( result.Count <= 0 )
{
return null;
}
else
{
return result.ToArray();
}
}
}
/// <summary>
/// Decompress a byte stream that was formerly compressed
/// with the CompressFile() routine with the ZIP algorithm and
/// store it to a file.
/// </summary>
/// <param name="sourceFilePath">The source file path.</param>
/// <param name="destinationFilePath">The file path where the file will be
/// stored.</param>
public static void DecompressFile(
FileInfo sourceFilePath,
FileInfo destinationFilePath )
{
DecompressFile(
sourceFilePath.FullName,
destinationFilePath.FullName );
}
/// <summary>
/// Decompress a byte stream that was formerly compressed
/// with the CompressFile() routine with the ZIP algorithm and
/// store it to a file.
/// </summary>
/// <param name="sourceFilePath">The source file path.</param>
/// <param name="destinationFilePath">The file path where the file will be
/// stored.</param>
public static void DecompressFile(
string sourceFilePath,
FileInfo destinationFilePath )
{
DecompressFile(
sourceFilePath,
destinationFilePath.FullName );
}
/// <summary>
/// Decompress a byte stream that was formerly compressed
/// with the CompressFile() routine with the ZIP algorithm and
/// store it to a file.
/// </summary>
/// <param name="sourceFilePath">The source file path.</param>
/// <param name="destinationFilePath">The file path where the file will be
/// stored.</param>
public static void DecompressFile(
FileInfo sourceFilePath,
string destinationFilePath )
{
DecompressFile(
sourceFilePath.FullName,
destinationFilePath );
}
/// <summary>
/// Decompress a byte stream that was formerly compressed
/// with the CompressFile() routine with the ZIP algorithm and
/// store it to a file.
/// </summary>
/// <param name="sourceFilePath">The source file path.</param>
/// <param name="destinationFilePath">The file path where the file will be
/// stored.</param>
public static void DecompressFile(
string sourceFilePath,
string destinationFilePath )
{
//if ( File.Exists( destinationFilePath ) )
//{
// File.Delete( destinationFilePath );
//}
//using ( FileStream sourceFS = new FileStream(
// sourceFilePath,
// FileMode.Open,
// FileAccess.Read ) )
//using ( BinaryReader r = new BinaryReader( sourceFS ) )
//using ( FileStream destinationFS = new FileStream(
// destinationFilePath,
// FileMode.CreateNew,
// FileAccess.Write ) )
//using ( BinaryWriter w = new BinaryWriter( destinationFS ) )
//{
// byte[] input = new byte[sourceFS.Length];
// r.Read( input, 0, (int)sourceFS.Length );
// byte[] buf = DecompressBytes( input );
// w.Write( buf );
//}
if ( File.Exists( destinationFilePath ) )
{
File.Delete( destinationFilePath );
}
using ( var sourceStream = new FileStream(
sourceFilePath,
FileMode.Open,
FileAccess.Read ) )
using ( var stm = new ZipInputStream( sourceStream ) )
{
// Only take the first one.
if ( stm.GetNextEntry() != null )
{
using ( var destinationStream = new FileStream(
destinationFilePath,
FileMode.CreateNew,
FileAccess.Write ) )
{
var data = new byte[4096];
while ( true )
{
var size = stm.Read( data, 0, data.Length );
if ( size > 0 )
{
destinationStream.Write( data, 0, size );
}
else
{
break;
}
}
}
}
}
}
/// <summary>
/// Decompress a byte stream that was formerly compressed
/// with the CompressFile() routine with the ZIP algorithm and
/// store it to a file.
/// </summary>
/// <param name="input">The buffer that contains the compressed
/// stream with the file.</param>
/// <param name="filePath">The file path.</param>
public static void DecompressFile(
byte[] input,
FileInfo filePath )
{
DecompressFile( input, filePath.FullName );
}
/// <summary>
/// Decompress a byte stream that was formerly compressed
/// with the CompressFile() routine with the ZIP algorithm and
/// store it to a file.
/// </summary>
/// <param name="input">The buffer that contains the compressed
/// stream with the file.</param>
/// <param name="filePath">The file path.</param>
public static void DecompressFile(
byte[] input,
string filePath )
{
if ( File.Exists( filePath ) )
{
File.Delete( filePath );
}
using ( var fs = new FileStream(
filePath,
FileMode.CreateNew,
FileAccess.Write ) )
using ( var w = new BinaryWriter( fs ) )
{
byte[] buf = DecompressBytes( input );
w.Write( buf );
}
}
/// <summary>
/// Decompress a byte stream of an XML document that was formerly
/// compressed with the <c>CompressXmlDocument()</c> routine with
/// the ZIP algorithm.
/// </summary>
/// <param name="input">The buffer that contains the compressed
/// stream with the XML document.</param>
/// <returns>Returns the decompressed XML document.</returns>
public static XmlDocument DecompressXmlDocument(
byte[] input )
{
var doc = new XmlDocument();
doc.LoadXml( DecompressString( input ) );
return doc;
}
/// <summary>
/// Decompress a byte stream of a string that was formerly
/// compressed with the CompressString() routine with the ZIP algorithm.
/// </summary>
/// <param name="input">The buffer that contains the compressed
/// stream with the string.</param>
/// <returns>Returns the decompressed string.</returns>
public static string DecompressString(
byte[] input )
{
return Encoding.UTF8.GetString( DecompressBytes( input ) );
}
/// <summary>
/// Decompress a byte stream of a <see cref="DataSet"/> that was formerly
/// compressed with the CompressDataSet() routine with the ZIP algorithm.
/// </summary>
/// <param name="input">The buffer that contains the compressed
/// stream with the <see cref="DataSet"/>.</param>
/// <returns>Returns the decompressed <see cref="DataSet"/>.</returns>
public static DataSet DecompressDataSet(
byte[] input )
{
var bf = new BinaryFormatter();
var buffer = DecompressBytes( input );
using ( var ms = new MemoryStream( buffer ) )
{
return (DataSet)bf.Deserialize( ms );
}
}
/// <summary>
/// Decompress a byte stream that was formerly compressed
/// with the CompressBytes() routine with the ZIP algorithm.
/// </summary>
/// <param name="input">The buffer that contains the compressed
/// stream with the bytes.</param>
/// <returns>Returns the decompressed bytes.</returns>
public static byte[] DecompressBytes(
byte[] input )
{
using ( var mem = new MemoryStream( input ) )
using ( var stm = new ZipInputStream( mem ) )
using ( var mem2 = new MemoryStream() )
{
var entry = stm.GetNextEntry();
if ( entry != null )
{
var data = new byte[4096];
while ( true )
{
var size = stm.Read( data, 0, data.Length );
if ( size > 0 )
{
mem2.Write( data, 0, size );
}
else
{
break;
}
}
}
using ( var r = new BinaryReader( mem2 ) )
{
var c = new byte[mem2.Length];
mem2.Seek( 0, SeekOrigin.Begin );
r.Read( c, 0, (int)mem2.Length );
return c;
}
}
}
// ------------------------------------------------------------------
#endregion
}
/////////////////////////////////////////////////////////////////////////
}