Salient Solutions

wrasslin ones and nones for fun and profit - Sky Sanders' Blog
posts - 96, comments - 70, 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

Gravatar

# re: SharpZipLib: recursively zip/unzip directory structure

posting items panerai replica on the Internet like the replica watches frank muller group's epic poem said, "I lv ring don't know what the rules cheap tiffany jewelry ought to be. " Jeffrey
10/20/2010 2:41 PM | swiss watch replica

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 3 and 1 and type the answer here:

Powered by: