Salient Solutions

wrasslin ones and nones for fun and profit - Sky Sanders' Blog
Get your own ranked flair here
posts - 92, comments - 103, trackbacks - 0

SharpZipLib: recursively zip/unzip directory structure

// Project: Salient
// http://salient.codeplex.com
// 
// Copyright 2010, Sky Sanders <sky at skysanders.net>
// Dual licensed under the MIT or GPL Version 2 licenses.
// http://salient.codeplex.com/license
//  
// Date: May 24 2010 

#region

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ICSharpCode.SharpZipLib.Zip;

#endregion

namespace Salient.IO.Compression
{
    public static class DirectoryCompression
    {
        public static void CompressDirectory(this Stream target, string sourcePath,
                                             Func<string, bool> excludeFromCompression)
        {
            sourcePath = Path.GetFullPath(sourcePath);

            string parentDirectory = Path.GetDirectoryName(sourcePath);

            int trimOffset = (string.IsNullOrEmpty(parentDirectory)
                                  ? Path.GetPathRoot(sourcePath).Length
                                  : parentDirectory.Length);


            List<string> fileSystemEntries = new List<string>();

            fileSystemEntries
                .AddRange(Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories)
                              .Select(d => d + "\\"));

            fileSystemEntries
                .AddRange(Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories));


            using (ZipOutputStream compressor = new ZipOutputStream(target))
            {
                compressor.SetLevel(9);

                foreach (string filePath in fileSystemEntries)
                {
                    if (excludeFromCompression(filePath))
                    {
                        continue;
                    }

                    compressor.PutNextEntry(new ZipEntry(filePath.Substring(trimOffset)));

                    if (filePath.EndsWith(@"\"))
                    {
                        continue;
                    }

                    byte[] data = new byte[2048];

                    using (FileStream input = File.OpenRead(filePath))
                    {
                        int bytesRead;

                        while ((bytesRead = input.Read(data, 0, data.Length)) > 0)
                        {
                            compressor.Write(data, 0, bytesRead);
                        }
                    }
                }

                compressor.Finish();
            }
        }


        public static void DecompressToDirectory(this Stream source, string targetPath, string pwd,
                                                 Func<string, bool> excludeFromDecompression)
        {
            targetPath = Path.GetFullPath(targetPath);

            using (ZipInputStream decompressor = new ZipInputStream(source))
            {
                if (!string.IsNullOrEmpty(pwd))
                {
                    decompressor.Password = pwd;
                }

                ZipEntry entry;

                while ((entry = decompressor.GetNextEntry()) != null)
                {
                    if (excludeFromDecompression(entry.Name))
                    {
                        continue;
                    }

                    string filePath = Path.Combine(targetPath, entry.Name);

                    string directoryPath = Path.GetDirectoryName(filePath);


                    if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath))
                    {
                        Directory.CreateDirectory(directoryPath);
                    }

                    if (entry.IsDirectory)
                    {
                        continue;
                    }

                    byte[] data = new byte[2048];
                    using (FileStream streamWriter = File.Create(filePath))
                    {
                        int bytesRead;
                        while ((bytesRead = decompressor.Read(data, 0, data.Length)) > 0)
                        {
                            streamWriter.Write(data, 0, bytesRead);
                        }
                    }
                }
            }
        }
    }
}

Usage

 

using System;
using System.IO;
using NUnit.Framework;
using Salient.IO.Compression;

namespace CoreFiveConnector.Tests
{
    [TestFixture]
    public class Class1
    {
        [Test]
        public void Test()
        {
            Func<string, bool> excludeFromCompression = path => { return false; };

            MemoryStream compressed = new MemoryStream();


            compressed.CompressDirectory("c:\\Temp", excludeFromCompression);


            // sharpzip closes the target so we need to create a new seekable  stream
            MemoryStream compressed2 = new MemoryStream(compressed.ToArray());

            Func<string, bool> excludeFromDecompression = path => { return false; };

            compressed2.DecompressToDirectory("c:\\Temp2", null, excludeFromDecompression);
        }
    }
}

Print | posted on Sunday, May 23, 2010 7:10 PM |

Feedback

No comments posted yet.

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 2 and 8 and type the answer here:

Powered by: