Many times we come across features that are around to implement and there are hardly any information available online. I tried to implement compress files to zip format in .NET 3.5 but hardly found any information. In 4.5 Microsoft provided new assembly System.IO.Compression.FileSystem.dll to create Zip file easily but it is not the case in 3.5.
At the same time there are many ways to compress files; hence decided to create separate assembly which can be referenced by any solution in .NET 3.5 or higher. There are some free zip libraries available but decided to go against that to have a control over the implementation. One main reason is frequently change in requirement, it will be easy for us to change the implementation without making any major change in calling solutions.
In this implementation, considering comtaility in .NET 3.5 implemented Zipping using System.IO.Packaging in WindowsBase.dll, external library DotNetZip and using Shell32.dll. DotNetZip is an free library available and used it here for the purpose of knowledge only. Actual implementation doesn't have the implementation of DotNetZip.
But, lets first understand Factory Method
Wiki says - The factory method pattern is an object-oriented creational design pattern to implement the concept of factories and deals with the problem of creating objects (products) without specifying the exact class of object that will be created. The essence of this pattern is to "Define an interface for creating an object, but let the classes that implement the interface decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses."
Codeproject says - The Factory Method Design Pattern allows you to create objects without being bothered on what is the actual class being created. The benefit is that the client code (calling code) can just say "give me an object that can do XYZ" without knowing what is the actual class that can do "XYZ".
I opted to implement Factory Method using Abstract Class rather Interface because there are some commonality which I tried to implement in base class. So, lets first understand why and how I achieved it
Base class implementation has only those objects and methods which are common.
First implementation using System.IO.Packaging
Second implementation using DotNetZip
Now, here is the STAR of all and simply out of box implementation and full credit goes to Justin.
His codeproject.com article is the reference from where I derived this implementation. This implementation implemented in two steps. 1st Step create empty Zip file and 2nd Step add files in the Zip file. To add reference choose COM tab of the "Add Reference" screen and add the component named "Microsoft Shell Controls And Automation".
Now, lets see how these features implemented in a sample console application and how easily these three can be interchanged. If you see just changing the Creator class constructor we can change the whole implementation.
At the same time there are many ways to compress files; hence decided to create separate assembly which can be referenced by any solution in .NET 3.5 or higher. There are some free zip libraries available but decided to go against that to have a control over the implementation. One main reason is frequently change in requirement, it will be easy for us to change the implementation without making any major change in calling solutions.
In this implementation, considering comtaility in .NET 3.5 implemented Zipping using System.IO.Packaging in WindowsBase.dll, external library DotNetZip and using Shell32.dll. DotNetZip is an free library available and used it here for the purpose of knowledge only. Actual implementation doesn't have the implementation of DotNetZip.
But, lets first understand Factory Method
Wiki says - The factory method pattern is an object-oriented creational design pattern to implement the concept of factories and deals with the problem of creating objects (products) without specifying the exact class of object that will be created. The essence of this pattern is to "Define an interface for creating an object, but let the classes that implement the interface decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses."
Codeproject says - The Factory Method Design Pattern allows you to create objects without being bothered on what is the actual class being created. The benefit is that the client code (calling code) can just say "give me an object that can do XYZ" without knowing what is the actual class that can do "XYZ".
I opted to implement Factory Method using Abstract Class rather Interface because there are some commonality which I tried to implement in base class. So, lets first understand why and how I achieved it
Base class implementation has only those objects and methods which are common.
// FACTORY CLASS public abstract class ArchiveObj { internal String strPath; internal List<String> lError; internal List<String> lFiles; public String[] ErrorList { get { return lError.ToArray(); } } public ArchiveObj() { lFiles = new List<string>(); lError = new List<string>(); } public Boolean AddFile(String strFile) { lFiles.Add(strFile); return true; } public abstract int SaveArchive(); } // CREATOR CLASS public abstract class ArchiveCreator { internal String strPath; public abstract ArchiveObj GetArchieve(); }
First implementation using System.IO.Packaging
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO.Packaging; namespace Archive { class WinBaseZip : ArchiveObj { private WinBaseZip(){} public WinBaseZip(String sPath) { strPath = sPath; } public override int SaveArchive() { foreach (String strFile in lFiles) zipFile(strFile); if (lError.Count > 0) { if (lError.Count < lFiles.Count) return 0; else return -1; } return 1; } private bool zipFile(String strFile) { PackagePart pkgPart = null; using (Package Zip = Package.Open(strPath, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite)) { String strTemp = strFile.Replace(" ", "_"); String zipURI = String.Concat("/", System.IO.Path.GetFileName(strTemp)); Uri parturi = new Uri(zipURI, UriKind.Relative); try { pkgPart = Zip.CreatePart(parturi, System.Net.Mime.MediaTypeNames.Application.Zip, CompressionOption.Normal); } catch(Exception ex) { lError.Add(strFile + "; Error : " + ex.Message); return false; } Byte[] bites = System.IO.File.ReadAllBytes(strFile); pkgPart.GetStream().Write(bites, 0, bites.Length); Zip.Close(); } return true; } } public class WinBaseZipCreator : ArchiveCreator { private WinBaseZipCreator(){} public WinBaseZipCreator(String sPath) { strPath = sPath; } public override ArchiveObj GetArchieve() { return new WinBaseZip(strPath); } } }
Second implementation using DotNetZip
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Ionic.Zip; namespace Archive { class IonicZip : ArchiveObj { private IonicZip(){} public IonicZip(String sPath) { strPath = sPath; } public override int SaveArchive() { ZipFile zip = new ZipFile(); foreach (String strFile in lFiles) zip.AddFile(strFile); zip.Save(strPath); return 1; } } public class IonicZipCreator : ArchiveCreator { private IonicZipCreator() { } public IonicZipCreator(String sPath) { strPath = sPath; } public override ArchiveObj GetArchieve() { return new IonicZip(strPath); } } }
Now, here is the STAR of all and simply out of box implementation and full credit goes to Justin.
His codeproject.com article is the reference from where I derived this implementation. This implementation implemented in two steps. 1st Step create empty Zip file and 2nd Step add files in the Zip file. To add reference choose COM tab of the "Add Reference" screen and add the component named "Microsoft Shell Controls And Automation".
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO.Compression; using Shell32; namespace Archive { class ZipShell : ArchiveObj { private ZipShell(){} public ZipShell(String sPath) { strPath = sPath; } public override int SaveArchive() { CreateZip(strPath); foreach (String strFile in lFiles) ZipCopyFile(strFile); return 1; } public bool CreateZip(String strZipFile) { try { System.Text.ASCIIEncoding Encoder = new System.Text.ASCIIEncoding(); byte[] baHeader = System.Text.Encoding.ASCII.GetBytes(("PK" + (char)5 + (char)6).PadRight(22, (char)0)); System.IO.FileStream fs = System.IO.File.Create(strZipFile); fs.Write(baHeader, 0, baHeader.Length); fs.Flush(); fs.Close(); fs = null; } catch(Exception ex) { } return true; } private bool ZipCopyFile(String strFile) { Shell32.Shell Shell = new Shell32.Shell(); int iCnt = Shell.NameSpace(strPath).Items().Count; Shell.NameSpace(strPath).CopyHere(strFile, 0); // Copy file in Zip if (Shell.NameSpace(strPath).Items().Count == (iCnt + 1)) { System.Threading.Thread.Sleep(100); } return true; } } public class ZipShellCreator : ArchiveCreator { private ZipShellCreator() { } public ZipShellCreator(String sPath) { strPath = sPath; } public override ArchiveObj GetArchieve() { return new ZipShell(strPath); } } }
Now, lets see how these features implemented in a sample console application and how easily these three can be interchanged. If you see just changing the Creator class constructor we can change the whole implementation.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Archive; // Added reference of new assembly namespace TestConsole { class Program { static void Main(string[] args) { ArchiveCreator ss = new WinBaseZipCreator(@"d:\testzip1.zip"); ArchiveObj xx = ss.GetArchieve(); xx.AddFile(@"d:\TEST1.txt"); xx.AddFile(@"d:\TEST2.txt"); xx.SaveArchive(); ArchiveCreator sss = new IonicZipCreator(@"d:\testzip2.zip"); ArchiveObj xxx = sss.GetArchieve(); xxx.AddFile(@"d:\TEST1.txt"); xxx.AddFile(@"d:\TEST2.txt"); xxx.SaveArchive(); ArchiveCreator ssss = new ZipShellCreator(@"d:\testzip3.zip"); ArchiveObj xxxx = ssss.GetArchieve(); xxxx.AddFile(@"d:\TEST1.txt"); xxxx.AddFile(@"d:\TEST2.txt"); xxxx.SaveArchive(); } } }
This is an excellent implementation but here I see that you didnt coded for List lError, I am assuming that you left it to user to implement it.
ReplyDeleteJak
Hi Jak,
DeleteThanks... yes i kept the error handling incomplete... let the user implement it as per their requirement.
Hi thanks for the article. Its working fine. But pls explain the code.
ReplyDeleteWhat an excellent code u have here, perfect structure, but as for beginners it will be a little bit hard to understand it from the first time. Thats why I suggest everyone to learn how to open .zip file https://wikiext.com/zip if you dont know PC at all.
ReplyDeleteVery nice post I really enjoyed it...You can also visit my website for
ReplyDeleteCall Girls in Bangalore
Call Girls in Kolkata
Call Girls in Lucknow
Call Girls in Jammu
Call Girls in Chandigarh
Call Girls in Guwahati
Call Girls in Ranchi
Call Girls in Gurgaon
Call girls in Chandigarh
Call girls in Mumbai
I have read your blog its very attractive and impressive. I like it your blog.
DeleteFinal Year Projects for CSE in Dot Net
.Net Training in Chennai
Final Year Project Centers in Chennai
Dot Net Training in Chennai
Very nice post I really enjoyed it...You can also visit my website for
ReplyDeleteEscorts in Bangalore
Escorts in Kolkata
Escorts in Lucknow
Escorts in Jammu
Escorts in Chandigarh
Escorts in Guwahati
Escorts in Ranchi
Escorts in Gurgaon
Escorts in Chandigarh
Very nice post I really enjoyed it...You can also visit my website for
ReplyDeleteEscort services in Bangalore
Escort services in Kolkata
Escort services in Lucknow
Escort services in Jammu
Escort services in Chandigarh
Escort services in Guwahati
Escort services in Ranchi
Escort services in Gurgaon
Escort services in Chandigarh
Escort services in Mumbai
Loved your post...You can also visit my website for
ReplyDeleteBangalore escorts
Kolkata escorts
Lucknow escorts
Jammu escorts
Chandigarh escorts
Very nice post I really enjoyed it...You can also visit my website for
ReplyDeleteCall girls in Bangalore
Call girls in Kolkata
Call girls in Lucknow
Call girls in Jammu
Call Girls in Chandigarh
Call girls in Guwahati
ReplyDeleteCall girls in Ranchi
Call girls in Gurgaon
Call girls in Chandigarh
Call girls in Mumbai
Call girls in Pune
If you are in Jaipur and need beautiful Call Girls in Jaipur or white skin Call Girls in Jaipur then you can simply book call girls in Jaipur from one of the best escort agency named Call Girls in Jaipur. It is No.1 premier escort agency and provide both incall or outcall facility to clients.Please click on the following link to check the official websites Call Girls in Jaipur
ReplyDeleteCall Girls in Kolkata
ReplyDeleteCall Girls in Mumbai
Call Girls in Lucknow
Call Girls in Gurgaon
Call Girls in Bangalore
Call Girls in Guwahati
======================
Escorts
======================
Escorts in Kolkata
Escorts in Mumbai
Escorts in Lucknow
Escorts in Gurgaon
Escorts in Bangalore
Escorts in Guwahati
Escort services
======================
Escort services in Kolkata
Mumbai Escort Service
Escort services in Lucknow
Escort services in Gurgaon
Escort services in Bangalore
Escort services in Guwahati
======================
Escort service
======================
Escort Service in Kolkata
Escort Service in Mumbai
Escort Service in Lucknow
Escort Service in Gurgaon
Escort Service in Bangalore
Escort Service in Guwahati
THANK YOU FOR VISITING MY WEBSITE:-
ReplyDeleterussian escorts in gurgaon
housewife escorts in gurgaon
gurgaon escort services
gurgaon escorts
escorts in gurgaon
escort services in gurgaon
gurgaon call girls
call girls in gurgaon
THANK YOU FOR VISITING MY WEBSITE:-
Thanks for sharing this nice piece of information. I really loved reading it. In case you want to read mine kindly click bellow:-
ReplyDeleteEscort services in Guwahati
Escort services in Guwahati
Escort services in Guwahati
Escort services in Guwahati
Hello, This is a very interesting blog.
ReplyDeleteCollege escorts in guwahati
Housewife escorts in Guwahati
Assamese call girls in guwahati
Nepali escorts in Guwahati
High profile escorts in Guwahati
Call Girls in Guwahati
Guwahati call girls
Escorts in Guwahati