19

I want to compress a file and a directory in C#. I found some solution in Internet but they are so complex and I couldn't run them in my project. Can anybody suggest me a clear and effective solution?

mybirthname
  • 17,949
  • 3
  • 31
  • 55
eponymous
  • 2,090
  • 5
  • 23
  • 29
  • Why couldnt you run them in your project? – BugFinder Jun 22 '12 at 09:27
  • refer in .net 4.0 http://msdn.microsoft.com/en-us/library/ms404280.aspx – Romil Kumar Jain Jun 22 '12 at 09:28
  • 1
    possible duplicate of [How to compress a directory into a zip file programmatically](http://stackoverflow.com/questions/2498572/how-to-compress-a-directory-into-a-zip-file-programmatically) – ken2k Jun 22 '12 at 09:29
  • @BugFinder For example I found a solution in here http://cheeso.members.winisp.net/DotNetZipHelp/html/ca1725fb-8fbc-c786-feb9-672fabd9140d.htm bu I could not describe "ZipFile" in my project. Although I have added "using System.IO.Compression;" library, error didn't disappeared. There are a lot of code about ZipFile. Can be a problem about C#, Can i use this class in c#? – eponymous Jun 22 '12 at 09:49
  • Did you download the component that goes with the code you linked? – BugFinder Jun 22 '12 at 09:50
  • So thanks for your proposed solutions. I am examining them. – eponymous Jun 22 '12 at 10:01
  • Take a look at [7zip SDK](http://www.7-zip.org/sdk.html). If GZIP is not enough you can try 7z, LZMA or PPMd algorithms. – oleksii Jun 22 '12 at 10:24
  • @BugFinder I didn't download anything. I copied only snippet – eponymous Jun 22 '12 at 10:52
  • @Romil My code doesn't see CopyTo function. Do you have any suggestion about it? – eponymous Jun 22 '12 at 10:59
  • @ken2k I have an error in this line for "Ionic" ----> "using (var zip = new Ionic.Zip.ZipFile())" How can I solve this? Can i add any library? – eponymous Jun 22 '12 at 11:04
  • If you re-read the page you posted "a programmer" you will see the code is specifically for a zip file which this is an example for... they provide you with the missing class. – BugFinder Jun 22 '12 at 11:05
  • @Romil Yes, i am using c# 2.0 I created my project as .Net Framework 2.0 – eponymous Jun 22 '12 at 11:07
  • @aprogrammer, check my answer. You were facing the issue because FileStream.CopyTo() was introduced in 4.0 onwards. – Romil Kumar Jain Jun 22 '12 at 12:02
  • @Romil I created a project in 4.0 and succeeded to compress but it compressed only txt files in the first folder but i want to compress a directory. Do you have any solution about this? Thank you, – eponymous Jun 22 '12 at 14:21
  • @aprogrammer, refer http://stackoverflow.com/questions/2236025/how-can-i-compress-a-directory-with-net – Romil Kumar Jain Jun 22 '12 at 14:26
  • @BugFinder the c# code which in this link "http://cheeso.members.winisp.net/DotNetZipHelp/html/ca1725fb-8fbc-c786-feb9-672fabd9140d.htm" but it take only first subfolder. i used this line "zip.AddDirectory(path);" instead of first two line of the code block. So the code took all subfolders. And i added using "Ionic.Zip;" dll to my code. So thanks all of your helps. – eponymous Jun 27 '12 at 14:05

10 Answers10

25

You could use GZipStream in the System.IO.Compression namespace

.NET 2.0.

public static void CompressFile(string path)
{
    FileStream sourceFile = File.OpenRead(path);
    FileStream destinationFile = File.Create(path + ".gz");

    byte[] buffer = new byte[sourceFile.Length];
    sourceFile.Read(buffer, 0, buffer.Length);

    using (GZipStream output = new GZipStream(destinationFile,
        CompressionMode.Compress))
    {
        Console.WriteLine("Compressing {0} to {1}.", sourceFile.Name,
            destinationFile.Name, false);

        output.Write(buffer, 0, buffer.Length);
    }

    // Close the files.
    sourceFile.Close();
    destinationFile.Close();
}

.NET 4

public static void Compress(FileInfo fi)
    {
        // Get the stream of the source file.
        using (FileStream inFile = fi.OpenRead())
        {
            // Prevent compressing hidden and 
            // already compressed files.
            if ((File.GetAttributes(fi.FullName) 
                & FileAttributes.Hidden)
                != FileAttributes.Hidden & fi.Extension != ".gz")
            {
                // Create the compressed file.
                using (FileStream outFile = 
                            File.Create(fi.FullName + ".gz"))
                {
                    using (GZipStream Compress = 
                        new GZipStream(outFile, 
                        CompressionMode.Compress))
                    {
                        // Copy the source file into 
                        // the compression stream.
                    inFile.CopyTo(Compress);

                        Console.WriteLine("Compressed {0} from {1} to {2} bytes.",
                            fi.Name, fi.Length.ToString(), outFile.Length.ToString());
                    }
                }
            }
        }
    }

http://msdn.microsoft.com/en-us/library/ms404280.aspx

Darren
  • 68,902
  • 24
  • 138
  • 144
  • Thanks for your solution but i have an error about "CopyTo" in this snippet. I couldn't solve this. – eponymous Jun 22 '12 at 11:16
  • @Romil - no, the namespace is available in 2.0., I checked. You can also find proof at: http://msdn.microsoft.com/en-us/library/ms404280(v=vs.80).aspx – Darren Jun 22 '12 at 11:42
  • @DarrenDavies, inFile.CopyTo() function is not available in 2.0. it is available in 4.0 and onward. – Romil Kumar Jain Jun 22 '12 at 11:57
  • @Romil - I have included the .NET 2.0. example from MSDN. – Darren Jun 22 '12 at 12:03
  • I tried to use this snipped but i have a problem about reaching the file path. I have an error about it? What can be the reason about not to reach the file path? – eponymous Jun 22 '12 at 14:32
  • error ---> denied access to the "c:/Temp" path. What can be the reason of this? – eponymous Jun 24 '12 at 12:50
  • @Selen - maybe you don't have access to the folder/file with your account. Did this help? If so please mark it as the answer. – Darren Mar 19 '13 at 13:01
  • offtopic: in your if clause you should use the equal operator && and not the binary & – Bernhard Feb 02 '18 at 07:56
21

I'm adding this answer as I've found an easier way than any of the existing answers:

  1. Install DotNetZip DLLs in your solution (easiest way is to install the package from nuget)
  2. Add a reference to the DLL.
  3. Import the namespace by adding: using Ionic.Zip;
  4. Zip your file

Code:

using (ZipFile zip = new ZipFile())
{
    zip.AddFile("C:\test\test.txt");
    zip.AddFile("C:\test\test2.txt");
    zip.Save("C:\output.zip");
}

If you don't want the original folder structure mirrored in the zip file, then look at the overrides for AddFile() and AddFolder() etc.

NickG
  • 9,315
  • 16
  • 75
  • 115
  • Agreed, one of the easiest, if not, the easiest. – AMissico Oct 09 '13 at 00:45
  • 1
    It seems DotNetZip is since years no longer maintained and there is a bug in zipping certain big files: https://dotnetzip.codeplex.com/workitem/14087 I found it too scary to use a zip library which cannot add reliably files to an archieve. Can anyone confirm that DotNetZip has a problem ? – Peter Huber Jan 15 '15 at 06:12
  • 1
    @PeterHuber Yes it does have that bug, but the fix for it is on the link you posted. – NickG Jan 26 '16 at 13:17
3

For .Net Framework 4.5 this is the most clear example I found:

using System;
using System.IO;
using System.IO.Compression;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            string startPath = @"c:\example\start";
            string zipPath = @"c:\example\result.zip";
            string extractPath = @"c:\example\extract";

            ZipFile.CreateFromDirectory(startPath, zipPath);

            ZipFile.ExtractToDirectory(zipPath, extractPath);
        }
    }
}

You'll need to add a reference to System.IO.Compression.FileSystem

From: https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-compress-and-extract-files

2

There is a built-in class in System.IO.Packaging called the ZipPackage:

http://msdn.microsoft.com/en-us/library/system.io.packaging.zippackage(v=vs.100).aspx

Bas
  • 26,772
  • 8
  • 53
  • 86
1

http://www.icsharpcode.net/opensource/sharpziplib/

CarlosJ
  • 244
  • 3
  • 13
  • @aprogrammer You're welcome. I'm sorry for not posting some code but I don't know exactly where I have it and I don't have much time right now – CarlosJ Jun 22 '12 at 10:42
1

You can just use ms-dos command line program compact.exe. Look on a parameters compact.exe in cmd and start this process using .NET method Process.Start().

1

Using DotNetZip http://dotnetzip.codeplex.com/, there's an AddDirectory() method on the ZipFile class that does what you want:

using (var zip = new Ionic.Zip.ZipFile())
{
    zip.AddDirectory("DirectoryOnDisk", "rootInZipFile");
    zip.Save("MyFile.zip");
}

Bonne continuation...

1

just use following code for compressing a file.

       public void Compressfile()
        {
             string fileName = "Text.txt";
             string sourcePath = @"C:\SMSDBBACKUP";
             DirectoryInfo di = new DirectoryInfo(sourcePath);
             foreach (FileInfo fi in di.GetFiles())
             {
                 //for specific file 
                 if (fi.ToString() == fileName)
                 {
                     Compress(fi);
                 }
             } 
        }

public static void Compress(FileInfo fi)
        {
            // Get the stream of the source file.
            using (FileStream inFile = fi.OpenRead())
            {
                // Prevent compressing hidden and 
                // already compressed files.
                if ((File.GetAttributes(fi.FullName)
                    & FileAttributes.Hidden)
                    != FileAttributes.Hidden & fi.Extension != ".gz")
                {
                    // Create the compressed file.
                    using (FileStream outFile =
                                File.Create(fi.FullName + ".gz"))
                    {
                        using (GZipStream Compress =
                            new GZipStream(outFile,
                            CompressionMode.Compress))
                        {
                            // Copy the source file into 
                            // the compression stream.
                            inFile.CopyTo(Compress);

                            Console.WriteLine("Compressed {0} from {1} to {2} bytes.",
                                fi.Name, fi.Length.ToString(), outFile.Length.ToString());
                        }
                    }
                }
            }
        }

    }
Jeetendra Negi
  • 443
  • 3
  • 3
0

Use http://dotnetzip.codeplex.com/ to ZIP files or directory, there is no builtin class to do it directly in .NET

Arnaud F.
  • 8,252
  • 11
  • 53
  • 102
  • Thank you @Arnaud F. I saw this but my programme doesn't recognize ZipFile. How can i describe it in my programme? – eponymous Jun 22 '12 at 11:22
0

Source code taken from MSDN that is compatible to .Net 2.0 and above

public static void CompressFile(string path)
        {
            FileStream sourceFile = File.OpenRead(path);
            FileStream destinationFile = File.Create(path + ".gz");

            byte[] buffer = new byte[sourceFile.Length];
        sourceFile.Read(buffer, 0, buffer.Length);

        using (GZipStream output = new GZipStream(destinationFile,
            CompressionMode.Compress))
        {
            Console.WriteLine("Compressing {0} to {1}.", sourceFile.Name,
                destinationFile.Name, false);

            output.Write(buffer, 0, buffer.Length);
        }

        // Close the files.
        sourceFile.Close();
        destinationFile.Close();
    }  
Romil Kumar Jain
  • 20,239
  • 9
  • 63
  • 92
  • I tried to use this snipped but i have a problem about reaching the file path. I have an error about it? What can be the reason about not to reach the file path? – eponymous Jun 22 '12 at 14:34
  • TRy to create file on D: Drive (other than OS drive). You should face access issue in windows 7, catch the exception in try...catch and verify. – Romil Kumar Jain Jun 24 '12 at 13:18