Zip / Unzip folders and files with C#

By Peter Bromberg

The .NET Framework includes GZipStream and related classes, but they only support compression, not the standard ZIP file structure. This article explains how you can handle correctly zipping and unzipping folders and files including using a zip password.

A-well-a don't you know about the bird?
Well, everybody knows that the bird is the word!  --
The Trashmen (1963)

The .NET Framework has GzipStream and DeflateStream classes for compression tasks, but they do not support the standard ZIP file / folder FileEntry mechanism to zip a folder with all its files and subfolders.

Fortunately, the ICSharpCode SharpZipLib project does support this, as well as passwords for zip files and compression level.

Here is a utility class I wrote that handles zipping or unzipping a folder with all its subfolders and contained files, using SharpZipLib:

 

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

namespace FolderZipper
{
    public static class ZipUtil
    {
        public static void ZipFiles(string inputFolderPath, string outputPathAndFile, string password)
        {
            ArrayList ar = GenerateFileList(inputFolderPath); // generate file list
            int TrimLength = (Directory.GetParent(inputFolderPath)).ToString().Length;
            // find number of chars to remove     // from orginal file path
            TrimLength += 1; //remove '\'
            FileStream ostream;
            byte[] obuffer;
            string outPath = inputFolderPath + @"\" + outputPathAndFile;
            ZipOutputStream oZipStream = new ZipOutputStream(File.Create(outPath)); // create zip stream
            if (password != null && password != String.Empty)
                oZipStream.Password = password;
            oZipStream.SetLevel(9); // maximum compression
            ZipEntry oZipEntry;
            foreach (string Fil in ar) // for each file, generate a zipentry
            {
                oZipEntry = new ZipEntry(Fil.Remove(0, TrimLength));
                oZipStream.PutNextEntry(oZipEntry);

                if (!Fil.EndsWith(@"/")) // if a file ends with '/' its a directory
                {
                    ostream = File.OpenRead(Fil);
                    obuffer = new byte[ostream.Length];
                    ostream.Read(obuffer, 0, obuffer.Length);
                    oZipStream.Write(obuffer, 0, obuffer.Length);
                }
            }
            oZipStream.Finish();
            oZipStream.Close();
        }


        private static ArrayList GenerateFileList(string Dir)
        {
            ArrayList fils = new ArrayList();
            bool Empty = true;
            foreach (string file in Directory.GetFiles(Dir)) // add each file in directory
            {
                fils.Add(file);
                Empty = false;
            }

            if (Empty)
            {
                if (Directory.GetDirectories(Dir).Length == 0)
                    // if directory is completely empty, add it
                {
                    fils.Add(Dir + @"/");
                }
            }

            foreach (string dirs in Directory.GetDirectories(Dir)) // recursive
            {
                foreach (object obj in GenerateFileList(dirs))
                {
                    fils.Add(obj);
                }
            }
            return fils; // return file list
        }


        public static void UnZipFiles(string zipPathAndFile, string outputFolder, string password, bool deleteZipFile)
        {
            ZipInputStream s = new ZipInputStream(File.OpenRead(zipPathAndFile));
            if (password != null && password != String.Empty)
                s.Password = password;
            ZipEntry theEntry;
            string tmpEntry = String.Empty;
            while ((theEntry = s.GetNextEntry()) != null)
            {
                string directoryName = outputFolder;
                string fileName = Path.GetFileName(theEntry.Name);
                // create directory 
                if (directoryName != "")
                {
                    Directory.CreateDirectory(directoryName);
                }
                if (fileName != String.Empty)
                {
                    if (theEntry.Name.IndexOf(".ini") < 0)
                    {
                        string fullPath = directoryName + "\\" + theEntry.Name;
                        fullPath = fullPath.Replace("\\ ", "\\");
                        string fullDirPath = Path.GetDirectoryName(fullPath);
                        if (!Directory.Exists(fullDirPath)) Directory.CreateDirectory(fullDirPath);
                        FileStream streamWriter = File.Create(fullPath);
                        int size = 2048;
                        byte[] data = new byte[2048];
                        while (true)
                        {
                            size = s.Read(data, 0, data.Length);
                            if (size > 0)
                            {
                                streamWriter.Write(data, 0, size);
                            }
                            else
                            {
                                break;
                            }
                        }
                        streamWriter.Close();
                    }
                }
            }
            s.Close();
            if (deleteZipFile)
                File.Delete(zipPathAndFile);
        }
    }
}
You can dowload the Visual Studio 2008 Solution, which includes a Windows Forms "Tester" app that allows you to test the class library. Note that I have not included any validation on the various textboxes, File and Folderbrowser dialogs. If you do not have Visual Studio 2008, just make a new blank solution and add the project files to it.
Popularity  (107408 Views)
Picture
Biography - Peter Bromberg
Peter Bromberg is a C# MVP, MCP, and .NET expert who has worked in banking, financial and telephony for over 20 years. Pete focuses exclusively on the .NET Platform, and currently develops SOA and other .NET applications for a Fortune 500 clientele. Peter enjoys producing digital photo collage with Maya,playing jazz flute, the beach, and fine wines. You can view Peter's UnBlog and IttyUrl sites. Follow Microsoft MVP
Create New Account
Article Discussion: Zip / Unzip folders and files with C#
Peter Bromberg posted at Monday, February 04, 2008 12:01 PM
reply
How to use this "utility class" to zip and store one excel file?
Ashok kumar replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM

Hi Pete,
Subject: Regarding "How to zip one excel file with the given utility class".

Thankyou very much since you have given one very beautiful article. But I could not understand how to use this utility class to zip and store one excel file.
My concern is:
01. How to zip one excel file with the given utility class?
02. How to store the .zipped file at one location?

Kind Regards,
Ashok kumar.
Software Engineer from Bangalore/India.

reply
Framework 2.0
Doug Odegaard replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM

Peter,

If I understand you correctly the standard framework libraries do not allow creating of ZIP files themselves but only compression in the life of the app.  Correct?  So SharpZipLib is the best alternative in your opinion?  I need to take photos and files in an ASP.NET app from a database and combine in a zip file for download to the user.  Thanks in advance.

Doug - Missoula, MT

reply
Correct.
Peter Bromberg replied to Doug Odegaard at Monday, February 04, 2008 12:59 PM
The .NET 2.0 Deflate and GZip stream classes only support compression. To make a zip file that is compatible with say, WinZip, you need to be able to create the zip headers that define the file and folder structure. SharpZipLib does this.
reply
If you want to zip and store one Excel file
Peter Bromberg replied to Ashok kumar at Monday, February 04, 2008 12:59 PM
you can either use the technique outlined in the article, or just use the compression classes. The standard Zip folder / file header structure as outlined in the article is considered the standard way to build a Zip file, even if it's only contents is a single Excel workbook.
reply
DotNetZip
Doug Odegaard replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
reply
Cleanup
Drew Miller replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
It seems prudent to me to wrap both the ZipOutputStream and FileStream with using statements, to ensure that the code is being properly disposed of.  Maybe I'm just overly cautious though ^_^
reply
Stream Closing
Ross Killip replied to Drew Miller at Monday, February 04, 2008 12:59 PM
I agree fully with drew - if for instance you want to zip a folder contents using this awesome bit of code, then delete the original files, to ensure the files are not locked by the zipping process (and thus can't be deleted) you need to ensure the ostream is closed, either by adding the line:ostream.Close(); after the oZipStream.Write(obuffer, 0, obuffer.Length); or by using using statements :)
Nice code snippet though, cheers. :)


                   
             
reply
ICSharpCode multiple RAR
padmanaban v replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
I saw your article on ICSharpCode while searching for code samples to use in our application. I hope you can help me regarding the following scenario.

 

      Now we are done with generating a cryatal report  with CR server XI and exported this to byte[] and decoded to pdf formated base64string. And this base64string will be saved in sql database.

 

      And using asp.net.mail we will send the mail with encoded base64string as attachememt. So the receiver of the mail will be able to open the attachent as PDF.[following this concept to schedule the report]

 

      Here we need your help. Because of constraint of mailing attachemnt size we are searching for possible solution. Is it possible to split the Exported byte[] in to muliple .rar files. And rar files should not be created physically but as stream. This stream will be converted to base64string and saved in database for the use of send mail and Receiver will extract this multiple rar files in one .pdf report?

 or could you able suggest different way?

reply
Error While deleting the files after zipping
Debarati Chattopadhyay replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM

Hello Peter

I am using your methods to zip all files in a perticular folder.  The function is doing the required operation, but after zipping the files when I am trying to delete the files its showing me the following error.

"The process cannot access the file because it is being used by another process."

I have closed all the file stream after zipping the file,

Can you suggest me why I am getting this error.

 

Thanks

Debarati

reply
You would have to post some sample code.
Peter Bromberg replied to Debarati Chattopadhyay at Monday, February 04, 2008 12:59 PM
All your streams (FileStream and derivatevs) must be closed before you can attempt a delete operation. But without seeing what your code actually looks like, it would be difficult to guess where the problem is.
reply
Problem with Zipping files
Debarati Chattopadhyay replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM

Hello Peter

Thanks for your response. I am using the same code as provided by you. I am furnishing the code below.

public static void ZipFiles(string inputFolderPath, string outputPathAndFile, string password)

{

FileStream ostream = null;

ZipOutputStream oZipStream = null;

ZipEntry oZipEntry = null;

byte[] obuffer;

//If the Zip stream already exists then

//My Input folder is c:\Test which contains 7 .txt files.

string outPath = inputFolderPath + @"\" + outputPathAndFile;

try

{

if (File.Exists(outPath))

{

File.Delete(outPath);

}

ArrayList ar = GenerateFileList(inputFolderPath); // generate file list

//remove the log file from the list.

int TrimLength = (Directory.GetParent(inputFolderPath)).ToString().Length;

// find number of chars to remove // from orginal file path

TrimLength += 1; 

oZipStream = new ZipOutputStream(File.Create(outPath)); // create zip stream

if (password != null && password != String.Empty)

oZipStream.Password = password;

oZipStream.SetLevel(9); // maximum compression

foreach (string Fil in ar) // for each file, generate a zipentry

{

oZipEntry = new ZipEntry(Fil.Remove(0, TrimLength));

oZipStream.PutNextEntry(oZipEntry);

if (!Fil.EndsWith(@"/")) // if a file ends with '/' its a directory

{

ostream = File.OpenRead(Fil);

obuffer = new byte[ostream.Length];

ostream.Read(obuffer, 0, obuffer.Length);

oZipStream.Write(obuffer, 0, obuffer.Length);

}

}

}

catch (Exception ex)

{

string strmg = ex.Message.ToString();

}

finally

{

ostream.Flush();

oZipStream.Finish();

ostream.Close();

ostream.Dispose();

ostream = null;

oZipStream.Close();

oZipStream.Dispose();

oZipStream = null;

oZipEntry = null;

obuffer = null;

//Delete the directory and all the files inside it.

Directory.Delete(inputFolderPath,true);

}

}

I have also written a function which will delete all the files on the folder and i have called that function after ziping the file( In that case i am commenting the Directory.Delete line in Zip function.)

Can you please suggest me why I am getting the error.

Thanks

Debarati

 

 

reply
i'm geting a compilation error
hepsy ii replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM

Compilation Error

BC30002: Type 'ZipInputStream' is not defined

Namespace or type specified in the Imports 'ICSharpCode.SharpZipLib.Zip' doesn't contain any public member or cannot be found

can u please help me

it worked fine on my local system, but it gives error online
i uploaded the dll in the bin folder online

thank u

reply
You need to add a ostream.Close(); to stop a handle leak
Colin Critch replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
if (!Fil.EndsWith(@"/")) // if a file ends with '/' its a directory
  {
        ostream = File.OpenRead(Fil);
        obuffer = new byte[ostream.Length];
        ostream.Read(obuffer, 0, obuffer.Length);

        oZipStream.Write(obuffer, 0, obuffer.Length);

        ostream.Close(); // stop read handle leak

  }

Thanks for the Code

Cheers

Colin

reply
error zipping files
Cristi Calinescu replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM

hi,

   i'm using the exact code given above.

 i'm also using

path = "c:\\test\\";

IcsZipper.ZipUtil.ZipFiles(path, "c:\\", "");

but i get the debug error: The given path's format is not supported.

at line

ZipOutputStream oZipStream = new ZipOutputStream(File.Create(outPath));

the outpath is "c:\\test\\\\c:\\"

 

Please advice:)

reply
Error! Help me please!
Dang Phi Hung replied to Cristi Calinescu at Monday, February 04, 2008 12:59 PM
I have using your application but when I zip with large file ( <500Mb) I have error!
Please help me! Thank
reply
ICSharpCode.SharpZipLib.Zip not working using meory stream
Rajesh Moturu replied to Dang Phi Hung at Monday, February 04, 2008 12:59 PM
 

I am trying to zip and unzip PPTX(2007) with the help of ICSharpCode.SharpZipLib.Zip in Memory stream.

I am trying to updated those xml files (Unzipped PPTX files) with input data,without disturbing the structure of the xml .

Finally I am ziping those xml files and writing to PPTX .

When I tried to open this pptx,throws an error saying Files are corrupted.

 my Question is

Is there any chance of corrupting the xml files while unzip in memory stream.

Plese find the sample code ;

using (ZipOutputStream outputFile = new ZipOutputStream(file))

            {

                using (MemoryStream templateBuffer = new MemoryStream((TemplateResources.OpenXmlPPT)))

                {

                    using (ZipInputStream templateFile = new ZipInputStream(templateBuffer))

                    {

                        ZipEntry entry;

                        while ((entry = templateFile.GetNextEntry()) != null)

                        {

                            ZipEntry newEntry = new ZipEntry(entry.Name);

                            outputFile.PutNextEntry(newEntry);

 

                            if (String.Equals(entry.Name, "ppt/embeddings/Microsoft_Office_Excel_Worksheet2.xlsx", StringComparison.OrdinalIgnoreCase))

                            {

 

                                WriteUnzipExcell(templateFile, outputFile, entry);

 

                             }

                            else if (String.Equals(entry.Name, "ppt/charts/chart2.xml", StringComparison.OrdinalIgnoreCase))

                            {

                                byte[] sharedbuffer = new byte[entry.Size];

                                templateFile.Read(sharedbuffer, 0, (int)entry.Size);

                                XDocument XChartDocument = XDocument.Load(new MemoryStream(sharedbuffer));

                                WriteChartDocument(XChartDocument);

 

                                var streamToWrite = GetStream(XChartDocument);

                                outputFile.Write(streamToWrite, 0, streamToWrite.Length);

 

                            }

                            else

                            {

                                CopyStreamToOutputFile(templateFile, outputFile);

                            }

 

                        }

                    }

                }

            }

 

 

reply
path is not supported
srini vasan replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
the given path is not supported
here that code:
 

private void button1_Click(object sender, EventArgs e)
      {
          ZipFiles("c:\\bnn\\","c:\\sri2","");
      }
reply
Venk replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
Hi Peter,
Thanks for the codes. I used these codes for zipping the pdf files, that works perfect. However, I can not unzip it to get the original files. it seems like invalid zip files and all the files are showing as some fixed size.
But when I use the Unzip function (FolderZipper.ZipUtil.UnZipFiles) from your code, it unzips and gets the perfect files.

Conclusion i had is - i should use same library's unzip function to get the files and can't use general winzip. Is my assumption true? Please suggest.

This is bit problematic as I am using it for a web application. The scenario is - I have few hundereds of pdf files in a folder in the server which I ZIP using this utility & prompt the web client to download the zipfile. Thats perfect!,
now I either allow user to unzip that himself OR give a feature in my app to unzip. Giving unzip feature is almost impossible in codebehind since it can't access client's computer's folder. (hence, it will unzip in server only).

Please suggest a solution. Thanks in advance.
reply
Sebastian replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
hello peter,

at first i would like to thank you for this nice piece of code which helped me understanding the usage of ziplib pretty fast.

at second i think i have found a tiny bug: it occurs when you zip a folder or file which is located in the root directory of your filesystem (i.e. C:\something\ or C:\something.txt). in this case the first item in your output file will have the name omething instead of something. this occurs in line 15 where you increment TrimLength.
while Directory.GetParent(@"C:\something\somethingelse.txt") will return C:\something and you have to cut one more to get somethingelse.txt, Directory.GetParent(@"C:\something") will return something and cutting one more will end in having omething instead of something as your zipped item name.

to prevent this you can insert the following line beyond TrimLength += 1; (in line 14)
if (Directory.GetParent(inputFolderPath).ToString() != Directory.GetDirectoryRoot(inputFolderPath))

with regards
sebastian
reply
MUJI replied to Sebastian at Monday, February 04, 2008 12:59 PM
Hello all,

first of all thanks for putting sucha good tips for zip/unzip a folder using c#

Me going through the same for the first time, I would like to know the following first

1) Where is this .dll [using ICSharpCode.SharpZipLib.Zip;]

2) if I would like to use the code in an online web application rather than console/window apln
    whether the code shown on the site requires any change?
3) whether the forum explaining the delete operation after zip is complete?

Any one could help me would be highly appreciated.

Thanks in advance

MUJI GOPINATH
SBBJ,JAIPUR
reply
edid replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
Hi,
Thanks for all your works, that really pretty from you.
I don't understand why you exclude .INI files when you decompress from .ZIP. Is there any reason ?
Thanks.
reply
Míchel replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
I want to make exactly the same you explained at this post, but I need to make it also with the other formats offered by SmartZipLib (bzip2, tar and gzip). Is it possible that you send me some examples? Thanks in advance
reply
Nick replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
I have spent all day on this.  I am using ICSharpCode.SharpZipLib to zip a folder.  Everything works until I upload it to my web host (details below).  Any help or pointers would be appreicated.

I am using the following code (2 versions shown below) to zip a folder and its sub-folder.  The folder is a WordPress theme.

The file structure is:

images\imagefile1.png

images\imagefile2.png

file1.php

file2.css

... etc.

When the zip file loads and unzips in WordPress (unzipped by php code), the result is that I get the same file structure as above PLUS - it creates duplicate image files with the "images\" as part of the file name.  Since this is an illegal file name on the server, it cannot be removed using a program or via FTP - the only way to remove it is to use the file manager on the server.

Again - all the files in the images subfolder are duplicated in the root folder with the folder name ie:

"images\imagefile1.png"

Here are 2 versions of the code I have tried:

1) I tried a simple version:

using ICSharpCode.SharpZipLib;
using ICSharpCode.SharpZipLib.Zip;

.............

        string zipFileName = folderName + ".zip";

        zipFileName = zipFileName.Replace("\\", "/"); // I tried it both ways - leaving the name alone and replacing like this
        folderName = folderName.Replace("\\", "/");  // I tried it both ways - leaving the name alone and replacing like this
        ICSharpCode.SharpZipLib.Zip.FastZip zipit = new ICSharpCode.SharpZipLib.Zip.FastZip();
        zipit.CreateZip(zipFileName, folderName, true, "");

2) And I tried this:

using ICSharpCode.SharpZipLib;
using ICSharpCode.SharpZipLib.Zip;

.............

        string zipFileName = folderName + ".zip";

        ZipOutputStream os = new ZipOutputStream(File.OpenWrite(zipFileName));
        FileStream fs;

        string[] filenames = Directory.GetFiles(folderName, "*", SearchOption.AllDirectories);

        foreach (string s in filenames)
        {
          string sourceFileName = s;

          string path = Path.GetFullPath(sourceFileName).Replace(folderName + "\\", "");

          ZipEntry ze = new ZipEntry(ZipEntry.CleanName(path));
          ze.CompressionMethod = CompressionMethod.Stored;
          os.UseZip64 = UseZip64.Off;

          os.PutNextEntry(ze);

          fs = File.OpenRead(sourceFileName);

          byte[] buff = new byte[1024];
          int n = 0;
          while ((n = fs.Read(buff, 0, buff.Length)) > 0)
          {
            os.Write(buff, 0, n);
          }
          fs.Close();
        }

        os.CloseEntry();
        os.Close();


I am using a Windows 7 PC with Visual Studio 2008 and c#.  I have the most recent version of ICSharpCode.SharpZipLib (as of today). Both versions of the above code produce zips I can read and extract on my local drive with no problems - its only when I upload to a web hosting Linux box via php that this problem occurs.

I hope I have given enough information.  Any help would be greatly appreciated.  Thank you in advance for your time.

~ Nick

reply
Peter Bromberg replied to Nick at Monday, February 04, 2008 12:59 PM
You might want to download and try DotNetZip from codeplex and use that. More full-featured.
reply
Alex replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
It's better to use using()  construction thus you will make sure that all files/streams are closed even if your throw an exception in the middle of you operation.

Right now the code is not exception robust - and there will be resource leakage in case of any unexpected errors.

Alex.

reply
Neeraj replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
Hi Peter

I found API to set the comment for zipping but i could not find any API to get the comment for zip files.

ZipOutputStream.SetComment("wqwqwqwqw");

but there is no method like

ZipInputStream   GetCommnet()
reply
Peter Bromberg replied to Neeraj at Monday, February 04, 2008 12:59 PM
You might want to have a look at dotnetzip which can be found on codeplex.com. It's come out since this quite old article, and has a  lot more supporting functions.
reply
swati replied to Rajesh Moturu at Monday, February 04, 2008 12:59 PM
Error 1 The type or namespace name 'ICSharpCode' could not be found (are you missing a using directive or an assembly reference?) D:\ashwini\WindowsApplication7\WindowsApplication7\Form1.cs 5 7 WindowsApplication7

reply
mangai replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
Thanks a lot it helps meee 
reply
Vaibhav replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
i got this code from net . How i use this code in my handler for download the zip files
Please reply

using System;
using System.Linq;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Core;
using System.Collections;
using System.Xml;
#region " Method to create Zip file"

      /// <summary>
      /// This function will Create the ZIP stream from given xml configuration file
      /// </summary>
      /// <param name="zipConfigXml">Zip XML configuration</param>
      /// <param name="zipStream">MemoryStream to fill the data - ByRef</param>
      public void MakeZipFile(string zipConfigXml, ref MemoryStream zipStream)
      {
        if (zipConfigXml == null) throw new ArgumentNullException("zipConfigXml");

        ZipOutputStream oZipStream = new ZipOutputStream(zipStream);

        // Check if the zip configuration XML is valid XML format or not
        // If it is not a valid XML Request then return the null stream.

        if (Functions.IsValidXmlData(zipConfigXml) == false)
        {
          zipStream = null;
        }
        else
        {
          XmlDocument zipXMLDoc = new XmlDocument();

          // Load the XML Download Confirguration
          zipXMLDoc.LoadXml(zipConfigXml);

          // Select the downloadParts Element to create a file list array
          XmlNodeList nodeListDownloadParts = zipXMLDoc.GetElementsByTagName("downloadParts");

          foreach (XmlNode nodeDownloadParts in nodeListDownloadParts)
          {
            CreateDownloadPartsFileList(nodeDownloadParts, null, ref oZipStream);
          }

        }

        oZipStream.Finish();
      }

public void CreateDownloadPartsFileList(XmlNode nodeDownloadParts, ArrayList aryElementPath, ref ZipOutputStream oZipStream)
      {
        XmlNode xnodWorking;
        ArrayList aryWorkingElementPath = new ArrayList();

        bool isSkipTheChildNode = false;

        if (aryElementPath != null)
        {
          foreach (string paths in aryElementPath)
          {
            aryWorkingElementPath.Add(paths);
          }
        }

        // Sometimes we have designed the child node for file operation.
        // This will not have any important information regarding the Zip file structure so we can skip
        if (nodeDownloadParts.NodeType == XmlNodeType.Element)
        {
          XmlNamedNodeMap xmlAttributes = nodeDownloadParts.Attributes;
          string fileRelativePath, fileAbsolutePath = null, zipFilePath;

          switch (nodeDownloadParts.Name)
          {
            case "folder": //Nodename = Folder
              if (xmlAttributes != null)
              {
                if (xmlAttributes.GetNamedItem("isData") != null)
                {
                  switch (xmlAttributes.GetNamedItem("isData").Value)
                  {
                    // isData = 0, This folder is just for the representation purpose. This Entry does NOT have any data.
                    case "0":
                      aryWorkingElementPath.Add(xmlAttributes.GetNamedItem("id").Value);
                      break;
                    // isData = 1, This folder is really a pointer to actual data. This Entry have a location to actual data to copy in the zip file.
                    case "1":
                      string folderPath = xmlAttributes.GetNamedItem("path").Value;
                      if (folderPath != null)
                      {
                        if (xmlAttributes.GetNamedItem("isCopyRootFolder") != null)
                        {
                          if (xmlAttributes.GetNamedItem("isCopyRootFolder").Value == "1")
                          {
                            aryWorkingElementPath.Add(Path.GetDirectoryName(folderPath));
                          }
                        }

                        ArrayList fileList = GenerateFileList(folderPath);
                        int trimLength = folderPath.Length;
                        fileRelativePath = string.Join("\\",
                                       (string[])
                                       aryWorkingElementPath.ToArray(typeof(string)));
                        foreach (string fileFullPath in fileList)
                        {
                          fileAbsolutePath = fileFullPath;
                          zipFilePath = fileRelativePath + fileFullPath.Remove(0, trimLength);
                          WriteToZip(fileAbsolutePath, zipFilePath, ref oZipStream);
                        }
                      }
                      break;
                    default:
                      break;
                  }
                }
              }
              break;
            case "file": //Nodename = File
              if (xmlAttributes != null) fileAbsolutePath = xmlAttributes.GetNamedItem("path").Value;
              fileRelativePath = string.Join("\\", (string[])aryWorkingElementPath.ToArray(typeof(string)));
              zipFilePath = fileRelativePath + "\\" + Path.GetFileName(fileAbsolutePath);

              // Check if the file node has childNodes or not
              // If there is a child node then we need to do some kind of operation with the file so
              // we need to do opearation and read that file in the buffer and add that buffer to zip file.
              if (nodeDownloadParts.HasChildNodes)
              {
                isSkipTheChildNode = true;
                MemoryStream zipMemStream = new MemoryStream();
                //UnicodeEncoding uniEncoding = new UnicodeEncoding();
                StreamWriter sw = new StreamWriter(zipMemStream) { AutoFlush = true };
                long count = 0;

                // Get the NodeList of EditLine from the file node
                XmlNodeList fileEditLineNodeList = nodeDownloadParts.SelectNodes("editLine");

                using (StreamReader r = new StreamReader(fileAbsolutePath))
                {
                  string line;
                  while ((line = r.ReadLine()) != null)
                  {
                    // Check in the EditLine NodeList if the criteria met replace the string
                    if (fileEditLineNodeList != null)
                    {
                      foreach (XmlNode fileEditLineNode in fileEditLineNodeList)
                      {
                        if (fileEditLineNode.Attributes != null)
                        {
                          if (line.Contains(fileEditLineNode.Attributes.GetNamedItem("from").Value))
                          {
                            line =
                              line.Replace(
                                fileEditLineNode.Attributes.GetNamedItem("from").Value,
                                fileEditLineNode.Attributes.GetNamedItem("to").Value);
                            break;
                          }
                        }
                      }
                    }
                    count++;
                    sw.WriteLine(line);
                  }
                }

                // Get the NodeList of AddLine from the file node
                XmlNodeList fileAddLineNodeList = nodeDownloadParts.SelectNodes("addLine");
                if (fileAddLineNodeList != null)
                {
                  foreach (XmlNode fileAddLineNode in fileAddLineNodeList)
                  {
                    string newLine = null;
                    if (fileAddLineNode.Attributes != null)
                    {
                      switch (fileAddLineNode.Attributes.GetNamedItem("type").Value)
                      {
                        // Depend on the file type if the criteria met replace the string accordingly
                        case "lstFile":
                          newLine = ("Reg" + count + fileAddLineNode.InnerText);
                          break;
                        default:
                          newLine = fileAddLineNode.InnerText;
                          break;
                      }
                    }
                    sw.WriteLine(newLine);
                    count++;
                  }
                }

                byte[] fileBuffer = zipMemStream.ToArray();

                sw.Close();

                WriteToZip(fileBuffer, zipFilePath, ref oZipStream);
              }
              else
              {
                WriteToZip(fileAbsolutePath, zipFilePath, ref oZipStream);
              }

              break;
            ///Nodename = filefromdatabase
            /// You can fetch the file from database by providing tablename and fileid.

            case "filefromdatabase":
              if (xmlAttributes != null)
              {
                string tableName = xmlAttributes.GetNamedItem("tablename").Value;
                string fileName = string.Empty;
                int fileId = Convert.ToInt32(xmlAttributes.GetNamedItem("fileid").Value);

                byte[] fileBuffer = Common.Functions.GetFileFromDatabase(this.MySqlConnectionString, tableName, fileId, ref fileName);

                fileRelativePath = string.Join("\\", (string[])aryWorkingElementPath.ToArray(typeof(string)));
                zipFilePath = fileRelativePath + "\\" + fileName;

                WriteToZip(fileBuffer, zipFilePath, ref oZipStream);

              }
              break;
            default:
              break;
          }
        }

        if ((nodeDownloadParts.HasChildNodes) && !isSkipTheChildNode)
        {
          xnodWorking = nodeDownloadParts.FirstChild;
          while (xnodWorking != null)
          {
            CreateDownloadPartsFileList(xnodWorking, aryWorkingElementPath, ref oZipStream);
            xnodWorking = xnodWorking.NextSibling;
          }
        }
      }
reply
samira xyz replied to Peter Bromberg at Monday, February 04, 2008 12:59 PM
Hello Peter,

i am very new to programming. I was given a task where i have write code to unzip the file and i have for string in zipfile name and then unzipping in to respective folder.


thanks 
Sunita


reply