Zip files in c#

Hi,

Does anyone know of a way to zip files in c#. I tried using sharplib but the compression utility that comes with XP is not able to unzip the files. I need a format that can be unzipped by this and most other compression tools since I am not sure exactly what my users will be using to unzip the files.

Thanks in advance

[328 byte] By [GBez] at [2007-12-16]
# 1
Hi,

Since you already tried SharpZip Lib, here's another way of zipping in C#. This uses a few J# Dlls.
http://msdn.microsoft.com/msdnmag/issues/03/06/zipcompression/default.aspx

Regards,
Vikram

Vikram at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Base Class Library...
# 2
To unzip files in Windows XP, zip files need to have entries that use relative paths.

For example, a zip file containing the following entry cannot be unzip by Windows XP:

c:\Temp\Myfile.txt

However this can:

Temp\Myfile.txt

You need to remove the root of the file name before using it in the ZipEntry, I use a function similar to this to do that:



public static string RemovePathRoot(string path)
{
string root = Path.GetPathRoot(path);
return path.Substring(root.Length);
}

I have quite happily used SharpZipLib and Windows XP together.

DavidM.Kean at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Base Class Library...
# 3
If you're interrested in paying for the zip component, i can reccomend xceedsoft Zip for .NET (http://www.xceedsoft.com) . They have a rather good implementation of Zip and an very good file system abstraction layer.
ToreBirkeland at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Base Class Library...
# 4

Do you mean I should be specifying a relative path for the zip file to be created in?

My code is as follows but I still cant read the file using XP's compression utility:

Note: These are my command line parameters that I start the app with:
"\Documents and Settings\gbezuidenhout\My Documents\ZipTest" "\Documents and Settings\gbezuidenhout\My Documents\Zipped.zip"

string
[] filenames = Directory.GetFiles(args[0]);

Crc32 crc = new Crc32();

ZipOutputStream s = new ZipOutputStream(File.Create(args[1]));

s.SetLevel(6); // 0 - store only to 9 - means best compression

foreach (string file in filenames) {

FileStream fs = File.OpenRead(file);

byte[] buffer = new byte[fs.Length];

fs.Read(buffer, 0, buffer.Length);

ZipEntry entry = new ZipEntry(file);

entry.DateTime = DateTime.Now;

// set Size and the crc, because the information

// about the size and crc should be stored in the header

// if it is not set it is automatically written in the footer.

// (in this case size == crc == -1 in the header)

// Some ZIP programs have problems with zip files that don't store

// the size and crc in the header.

entry.Size = fs.Length;

fs.Close();

crc.Reset();

crc.Update(buffer);

entry.Crc = crc.Value;

s.PutNextEntry(entry);

s.Write(buffer, 0, buffer.Length);

}

s.Finish();

s.Close();

GBez at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Base Class Library...
# 5
No, the files within the ZipEntry need to be relative.

For example:

This line:


ZipEntry entry = new ZipEntry(file);

Should be changed to call my method above:


ZipEntry entry = new ZipEntry(RemovePathRoot(file));

DavidM.Kean at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Base Class Library...
# 6
That works perfect, thanks. The only question I have now though is if I do use XP to open the file, it shows the entire directory structure down to the file that was zipped i.e. When you open the file as in the above example, you first see the folder Documents and Settings, then after going into that folder, gbezuidenhout all the way until you get to the file. I assume that is because the path property of the zipped file is that directory structure so I guess my question is, is there a way setting that property of the file to nothing after it has been zipped so that as soon as the user opens the file, he only sees the file that was zipped. I dont really want him to see the directory structure of the machine that the file was zipped on.
GBez at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Base Class Library...
# 7
Yes.
Use Path.GetFileName() instead of RemovePathRoot() above.
DavidM.Kean at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Base Class Library...
# 8
Sorted, thanks very much for your help.
GBez at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Base Class Library...
# 9
The J# solution is broke because the required assembly don't ship with .NET 2.0 beta 2. I don't want to use the sharp lib when the basic functionality is available in the framework. I wonder how hard it is to zip/unzip a folder using Sytem.IO.Compression. So far there is no sample code available, at least I didn't find any sample code.
stax0711 at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Base Class Library...
# 10
In .NET 2.0 you get some new compression functionality.
Take a look at the new System.IO.Compression Namespace.

Or here for more Information:
http://www.codeguru.com/Csharp/.NET/net_asp/files/article.php/c9931/

eclipse2k at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Base Class Library...
# 11
eclipse2k wrote:
In .NET 2.0 you get some new compression functionality.
Take a look at the new System.IO.Compression Namespace.

Or here for more Information:
http://www.codeguru.com/Csharp/.NET/net_asp/files/article.php/c9931/


I don't think this information will help me to zip a dir that can be unziped with WinRar and Co. because zip and gzip a different things.
stax0711 at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Base Class Library...
# 12
stax0711 wrote:
The J# solution is broke because the required assembly don't ship with .NET 2.0 beta 2. I don't want to use the sharp lib when the basic functionality is available in the framework. I wonder how hard it is to zip/unzip a folder using Sytem.IO.Compression. So far there is no sample code available, at least I didn't find any sample code.

You need to reproduce exactly what the SharpZibLib is doing anyway, so is it worth it?

DavidM.Kean at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Base Class Library...
# 13

stax0711 wrote:
I wonder how hard it is to zip/unzip a folder using Sytem.IO.Compression.

You can do it using the System.IO.Compression namespace BUT you have to add a "small" payload.
The Framework compression classes handle the ZIP-age of the data stream but you have to handle the ZIP file format by yourself! :) it has more than the zipped-data (headers, checksums, directory structure and so on)

I actually use this to unzip a single file.

'Data Array contains the .zip file

Dim Start, Lenght As Integer
Start = &H1E
Start += BitConverter.ToInt16(Data, &H1A)
Start += BitConverter.ToInt16(Data, &H1C)
Lenght = BitConverter.ToInt32(Data, &H12)
DataStream = New MemoryStream(Data, Start, Lenght)

Dim UncompStream As New MemoryStream
Dim DecStream As New Compression.DeflateStream(DataStream, Compression.CompressionMode.Decompress, True)
Dim Value As Integer = DecStream.ReadByte

Do Until Value = -1
UncompStream.WriteByte(CByte(Value))
Value = DecStream.ReadByte
Loop
DataStream.Close()

DataStream = UncompStream

You can find out more amour the .ZIP file format with any RFC about it on the web (I don't remember the rfc number. Simply open google and search zip file format structure pk deflated stored)
Or.. for a MOOOOORE complete (and complex) document look here.

Lino at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Base Class Library...

.NET Development

Site Classified