用.Net实现Zip

michael_wp原创

Michael_Jackson
头衔:我哪里有呀!:)
等级:小飞侠
财产:12660
经验:10258
魅力:3135
注册:2002-10-17
登录:2003-4-16
文章:462
签定:★不明32★

发贴时间: 2002-11-4 10:01:30

//ZipEntry.cs 
using System;
using System.IO;

namespace OrganicBit.Zip
{
    /// <summary>Specifies how the the zip entry should be compressed.</summary> 
    public enum CompressionMethod
    {
        /// <summary>No compression.</summary> 
        Stored = 0,

        /// <summary>Default and only supported compression method.</summary> 
        Deflated = 8
    }

    /// <summary>Specifies the amount of compression to apply to compressed zip entires.</summary> 
    public enum CompressionLevel : int
    {
        /// <summary>Default compression level.  A good choice for speed and size.</summary> 
        Default = -1,

        /// <summary>Do not perfrom compression.</summary> 
        None = 0,

        /// <summary>Compress the entry as fast as possible size trading size for time.</summary> 
        Fastest = 1,

        /// <summary>Compress the entry using a balance of size and time.</summary> 
        Average = 5,

        /// <summary>Compress the entry to smallest possible size trading time for size.</summary> 
        Smallest = 9
    }

    /// <summary>Represents a entry in a zip file.</summary> 
    public class ZipEntry
    {
        string _name = String.Empty;
        uint _crc = 0;
        long _compressedLength = -1;
        long _uncompressedLength = -1;
        byte[] _extraField = null;
        string _comment = String.Empty;
        DateTime _modifiedTime = DateTime.Now;

        CompressionMethod _method = CompressionMethod.Deflated;
        int _level = (int)CompressionLevel.Default;

        /// <summary>Initializes a instance of the <see cref="ZipEntry"/> class with the given name.</summary> 
        /// <param name="name">The name of entry that will be stored in the directory of the zip file.</param> 
        public ZipEntry(string name)
        {
            Name = name;
        }

        /// <summary>Creates a new Zip file entry reading values from a zip file.</summary> 
        internal ZipEntry(IntPtr handle)
        {
            ZipEntryInfo entryInfo;
            int result = 0;
            unsafe
            {
                result = ZipLib.unzGetCurrentFileInfo(handle, &entryInfo, null, 0, null, 0, null, 0);
            }
            if (result != 0)
            {
                throw new ZipException("Could not read entries from zip file " + Name);
            }

            ExtraField = new byte[entryInfo.ExtraFieldLength];
            sbyte[] entryNameBuffer = new sbyte[entryInfo.FileNameLength];
            sbyte[] commentBuffer = new sbyte[entryInfo.CommentLength];

            unsafe
            {
                result = ZipLib.unzGetCurrentFileInfo(handle, &entryInfo,
                    entryNameBuffer, (uint)entryNameBuffer.Length,
                    ExtraField, (uint)ExtraField.Length,
                    commentBuffer, (uint)commentBuffer.Length);
            }
            if (result != 0)
            {
                throw new ZipException("Could not read entries from zip file " + Name);
            }

            _name = ZipLib.AnsiToString(entryNameBuffer);
            _comment = ZipLib.AnsiToString(commentBuffer);

            _crc = entryInfo.Crc;
            _compressedLength = entryInfo.CompressedSize;
            _uncompressedLength = entryInfo.UncompressedSize;
            _method = (CompressionMethod)entryInfo.CompressionMethod;
            _modifiedTime = new DateTime(
                (int)entryInfo.DateTime.Year,
                (int)entryInfo.DateTime.Month + 1,
                (int)entryInfo.DateTime.Day,
                (int)entryInfo.DateTime.Hours,
                (int)entryInfo.DateTime.Minutes,
                (int)entryInfo.DateTime.Seconds);
        }

        /// <summary>Gets and sets the local file comment for the entry.</summary> 
        /// <remarks> 
        /// <para>Currently only Ascii 8 bit characters are supported in comments.</para> 
        /// <para>A comment cannot exceed 65535 bytes.</para> 
        /// </remarks> 
        public string Comment
        {
            get { return _comment; }
            set
            {
                // null comments are valid 
                if (value != null)
                {
                    if (value.Length > 0xffff)
                    {
                        throw new ArgumentOutOfRangeException("Comment cannot not exceed 65535 characters.");
                    }
                    if (!IsAscii(value))
                    {
                        throw new ArgumentException("Name can only contain Ascii 8 bit characters.");
                    }
                }

                // TODO: check for ASCII only characters 
                _comment = value;
            }
        }

        /// <summary>Gets the compressed size of the entry data in bytes, or -1 if not known.</summary> 
        public long CompressedLength
        {
            get { return _compressedLength; }
        }

        /// <summary>Gets the CRC-32 checksum of the uncompressed entry data.</summary> 
        public uint Crc
        {
            get { return _crc; }
        }

        /// <summary>Gets and sets the optional extra field data for the entry.</summary> 
        /// <remarks>ExtraField data cannot exceed 65535 bytes.</remarks> 
        public byte[] ExtraField
        {
            get
            {
                return _extraField;
            }
            set
            {
                if (value.Length > 0xffff)
                {
                    throw new ArgumentOutOfRangeException("ExtraField cannot not exceed 65535 bytes.");
                }
                _extraField = value;
            }
        }

        /// <summary>Gets and sets the default compresion method for zip file entries.  See <see cref="CompressionMethod"/> for a list of possible values.</summary> 
        public CompressionMethod Method
        {
            get { return _method; }
            set { _method = value; }
        }

        /// <summary>Gets and sets the default compresion level for zip file entries.  See <see cref="CompressionMethod"/> for a partial list of values.</summary> 
        public int Level
        {
            get { return _level; }
            set
            {
                if (value < -1 || value > 9)
                {
                    throw new ArgumentOutOfRangeException("Level", value, "Level value must be between -1 and 9.");
                }
                _level = value;
            }
        }

        /// <summary>Gets the size of the uncompressed entry data in in bytes.</summary> 
        public long Length
        {
            get { return _uncompressedLength; }
        }

        /// <summary>Gets and sets the modification time of the entry.</summary> 
        public DateTime ModifiedTime
        {
            get { return _modifiedTime; }
            set { _modifiedTime = value; }
        }

        /// <summary>Gets and sets the name of the entry.</summary> 
        /// <remarks> 
        /// <para>Currently only Ascii 8 bit characters are supported in comments.</para> 
        /// <para>A comment cannot exceed 65535 bytes.</para> 
        /// </remarks> 
        public string Name
        {
            get { return _name; }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException("Name cannot be null.");
                }
                if (value.Length > 0xffff)
                {
                    throw new ArgumentOutOfRangeException("Name cannot not exceed 65535 characters.");
                }
                if (!IsAscii(value))
                {
                    throw new ArgumentException("Name can only contain Ascii 8 bit characters.");
                }
                // TODO: check for ASCII only characters 
                _name = value;
            }
        }

        /// <summary>Flag that indicates if this entry is a directory or a file.</summary> 
        public bool IsDirectory
        {
            get
            {
                return (Length == 0 && CompressedLength == 0);
            }
        }

        /// <summary>Gets the compression ratio as a percentage.</summary> 
        /// <remarks>Returns -1.0 if unknown.</remarks> 
        public float Ratio
        {
            get
            {
                float ratio = -1.0f;
                if (Length > 0)
                {
                    ratio = Convert.ToSingle(Length - CompressedLength) / Length;
                }
                return ratio;
            }
        }

        /// <summary>Returns a string representation of the Zip entry.</summary> 
        public override string ToString()
        {
            return String.Format("{0} {1}", Name, base.ToString());
        }

        /// <summary>Check if <paramref name="str"/> only contains Ascii 8 bit characters.</summary> 
        static bool IsAscii(string str)
        {
            foreach (char ch in str)
            {
                if (ch > 0xff)
                {
                    return false;
                }
            }
            return true;
        }
    }
}

======================================================================

//ZipEntryCollection.cs
using System;
using System.Collections;

namespace OrganicBit.Zip
{
    /// <summary>A collection that stores <see cref='OrganicBit.Zip.ZipEntry'/> objects.</summary> 
    /// <seealso cref='OrganicBit.Zip.ZipEntryCollection'/> 
    [Serializable()]
    public class ZipEntryCollection : CollectionBase
    {
        /// <summary>Initializes a new instance of <see cref='OrganicBit.Zip.ZipEntryCollection'/>.</summary> 
        public ZipEntryCollection()
        {
        }

        /// <summary>Initializes a new instance of <see cref='OrganicBit.Zip.ZipEntryCollection'/> based on another <see cref='OrganicBit.Zip.ZipEntryCollection'/>.</summary> 
        /// <param name='value'>A <see cref='OrganicBit.Zip.ZipEntryCollection'/> from which the contents are copied.</param> 
        public ZipEntryCollection(ZipEntryCollection value)
        {
            this.AddRange(value);
        }

        /// <summary>Initializes a new instance of <see cref='OrganicBit.Zip.ZipEntryCollection'/> containing any array of <see cref='OrganicBit.Zip.ZipEntry'/> objects.</summary> 
        /// <param name='value'>A array of <see cref='OrganicBit.Zip.ZipEntry'/> objects with which to intialize the collection.</param> 
        public ZipEntryCollection(ZipEntry[] value)
        {
            this.AddRange(value);
        }

        /// <summary>Represents the entry at the specified index of the <see cref='OrganicBit.Zip.ZipEntry'/>.</summary> 
        /// <param name='index'><para>The zero-based index of the entry to locate in the collection.</para></param> 
        /// <value> 
        /// <para>The entry at the specified index of the collection.</para> 
        /// </value> 
        /// <exception cref='System.ArgumentOutOfRangeException'><paramref name='index'/> is outside the valid range of indexes for the collection.</exception> 
        public ZipEntry this[int index]
        {
            get
            {
                return ((ZipEntry)(List[index]));
            }
            set
            {
                List[index] = value;
            }
        }

        /// <summary>Adds a <see cref='OrganicBit.Zip.ZipEntry'/> with the specified value to the <see cref='OrganicBit.Zip.ZipEntryCollection'/>.</summary> 
        /// <param name='value'>The <see cref='OrganicBit.Zip.ZipEntry'/> to add.</param> 
        /// <returns>The index at which the new element was inserted.</returns> 
        /// <seealso cref='OrganicBit.Zip.ZipEntryCollection.AddRange'/> 
        public int Add(ZipEntry value)
        {
            return List.Add(value);
        }

        /// <summary>Copies the elements of an array to the end of the <see cref='OrganicBit.Zip.ZipEntryCollection'/>.</summary> 
        /// <param name='value'>An array of type <see cref='OrganicBit.Zip.ZipEntry'/> containing the objects to add to the collection.</param> 
        /// <returns>None.</returns> 
        /// <seealso cref='OrganicBit.Zip.ZipEntryCollection.Add'/> 
        public void AddRange(ZipEntry[] value)
        {
            for (int i = 0; (i < value.Length); i = (i + 1))
            {
                this.Add(value[i]);
            }
        }

        /// <summary>Adds the contents of another <see cref='OrganicBit.Zip.ZipEntryCollection'/> to the end of the collection.</summary> 
        /// <param name='value'>A <see cref='OrganicBit.Zip.ZipEntryCollection'/> containing the objects to add to the collection.</param> 
        /// <returns>None.</returns> 
        /// <seealso cref='OrganicBit.Zip.ZipEntryCollection.Add'/> 
        public void AddRange(ZipEntryCollection value)
        {
            for (int i = 0; (i < value.Count); i = (i + 1))
            {
                this.Add(value[i]);
            }
        }

        /// <summary>Gets a value indicating whether the <see cref='OrganicBit.Zip.ZipEntryCollection'/> contains the specified <see cref='OrganicBit.Zip.ZipEntry'/>.</summary> 
        /// <param name='value'>The <see cref='OrganicBit.Zip.ZipEntry'/> to locate.</param> 
        /// <returns> 
        /// <para><see langword='true'/> if the <see cref='OrganicBit.Zip.ZipEntry'/> is contained in the collection;  
        ///   otherwise, <see langword='false'/>.</para> 
        /// </returns> 
        /// <seealso cref='OrganicBit.Zip.ZipEntryCollection.IndexOf'/> 
        public bool Contains(ZipEntry value)
        {
            return List.Contains(value);
        }

        /// <summary>Copies the <see cref='OrganicBit.Zip.ZipEntryCollection'/> values to a one-dimensional <see cref='System.Array'/> instance at the specified index.</summary> 
        /// <param name='array'><para>The one-dimensional <see cref='System.Array'/> that is the destination of the values copied from <see cref='OrganicBit.Zip.ZipEntryCollection'/> .</para></param> 
        /// <param name='index'>The index in <paramref name='array'/> where copying begins.</param> 
        /// <returns>None.</returns> 
        /// <exception cref='System.ArgumentException'><para><paramref name='array'/> is multidimensional.</para> <para>-or-</para> <para>The number of elements in the <see cref='OrganicBit.Zip.ZipEntryCollection'/> is greater than the available space between <paramref name='arrayIndex'/> and the end of <paramref name='array'/>.</para></exception> 
        /// <exception cref='System.ArgumentNullException'><paramref name='array'/> is <see langword='null'/>. </exception> 
        /// <exception cref='System.ArgumentOutOfRangeException'><paramref name='arrayIndex'/> is less than <paramref name='array'/>'s lowbound. </exception> 
        /// <seealso cref='System.Array'/> 
        public void CopyTo(ZipEntry[] array, int index)
        {
            List.CopyTo(array, index);
        }

        /// <summary>Returns the index of a <see cref='OrganicBit.Zip.ZipEntry'/> in the <see cref='OrganicBit.Zip.ZipEntryCollection'/>.</summary> 
        /// <param name='value'>The <see cref='OrganicBit.Zip.ZipEntry'/> to locate.</param> 
        /// <returns> 
        /// <para>The index of the <see cref='OrganicBit.Zip.ZipEntry'/> of <paramref name='value'/> in the  
        /// <see cref='OrganicBit.Zip.ZipEntryCollection'/>, if found; otherwise, -1.</para> 
        /// </returns> 
        /// <seealso cref='OrganicBit.Zip.ZipEntryCollection.Contains'/> 
        public int IndexOf(ZipEntry value)
        {
            return List.IndexOf(value);
        }

        /// <summary>Inserts a <see cref='OrganicBit.Zip.ZipEntry'/> into the <see cref='OrganicBit.Zip.ZipEntryCollection'/> at the specified index.</summary> 
        /// <param name='index'>The zero-based index where <paramref name='value'/> should be inserted.</param> 
        /// <param name=' value'>The <see cref='OrganicBit.Zip.ZipEntry'/> to insert.</param> 
        /// <returns><para>None.</para></returns> 
        /// <seealso cref='OrganicBit.Zip.ZipEntryCollection.Add'/> 
        public void Insert(int index, ZipEntry value)
        {
            List.Insert(index, value);
        }

        /// <summary>Returns an enumerator that can iterate through the <see cref='OrganicBit.Zip.ZipEntryCollection'/>.</summary> 
        /// <returns><para>None.</para></returns> 
        /// <seealso cref='System.Collections.IEnumerator'/> 
        public new ZipEntryEnumerator GetEnumerator()
        {
            return new ZipEntryEnumerator(this);
        }

        /// <summary>Removes a specific <see cref='OrganicBit.Zip.ZipEntry'/> from the <see cref='OrganicBit.Zip.ZipEntryCollection'/>.</summary> 
        /// <param name='value'>The <see cref='OrganicBit.Zip.ZipEntry'/> to remove from the <see cref='OrganicBit.Zip.ZipEntryCollection'/> .</param> 
        /// <returns><para>None.</para></returns> 
        /// <exception cref='System.ArgumentException'><paramref name='value'/> is not found in the Collection. </exception> 
        public void Remove(ZipEntry value)
        {
            List.Remove(value);
        }

        /// <summary>Enumerator for <see cref="ZipEntryCollection"/>.</summary> 
        public class ZipEntryEnumerator : object, IEnumerator
        {

            private IEnumerator baseEnumerator;

            private IEnumerable temp;

            /// <summary>Initializes a new instance of the <see cref="ZipEntryEnumerator"/> class.</summary> 
            public ZipEntryEnumerator(ZipEntryCollection mappings)
            {
                this.temp = ((IEnumerable)(mappings));
                this.baseEnumerator = temp.GetEnumerator();
            }

            /// <summary>Gets the current entry.</summary> 
            public ZipEntry Current
            {
                get
                {
                    return ((ZipEntry)(baseEnumerator.Current));
                }
            }

            object IEnumerator.Current
            {
                get
                {
                    return baseEnumerator.Current;
                }
            }


            /// <summary>Advance the enumerator to the next entry in the collection.</summary> 
            /// <returns><c>true</c> if there are more entries; <c>false</c> if there are no more entires in the collection.</returns> 
            public bool MoveNext()
            {
                return baseEnumerator.MoveNext();
            }

            bool IEnumerator.MoveNext()
            {
                return baseEnumerator.MoveNext();
            }

            /// <summary>Set the enumerator to just before the start of the collection.  Call <see cref="MoveNext"/> to advance to the first entry in the collection.</summary> 
            public void Reset()
            {
                baseEnumerator.Reset();
            }

            void IEnumerator.Reset()
            {
                baseEnumerator.Reset();
            }
        }
    }
}

======================================================================

//ZipException.cs 
using System;
using System.Runtime.Serialization;

namespace OrganicBit.Zip
{

    /// <summary>Thrown whenever an error occurs during the build.</summary> 
    [Serializable]
    public class ZipException : ApplicationException
    {

        /// <summary>Constructs an exception with no descriptive information.</summary> 
        public ZipException() : base()
        {
        }

        /// <summary>Constructs an exception with a descriptive message.</summary> 
        /// <param name="message">The error message that explains the reason for the exception.</param> 
        public ZipException(String message) : base(message)
        {
        }

        /// <summary>Constructs an exception with a descriptive message and a reference to the instance of the <c>Exception</c> that is the root cause of the this exception.</summary> 
        /// <param name="message">The error message that explains the reason for the exception.</param> 
        /// <param name="innerException">An instance of <c>Exception</c> that is the cause of the current Exception. If <paramref name="innerException"/> is non-null, then the current Exception is raised in a catch block handling <paramref>innerException</paramref>.</param> 
        public ZipException(String message, Exception innerException) : base(message, innerException)
        {
        }

        /// <summary>Initializes a new instance of the BuildException class with serialized data.</summary> 
        /// <param name="info">The object that holds the serialized object data.</param> 
        /// <param name="context">The contextual information about the source or destination.</param> 
        public ZipException(SerializationInfo info, StreamingContext context) : base(info, context)
        {
        }
    }
}

======================================================================

//ZipLib.cs 
using System;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;

namespace OrganicBit.Zip
{

    /// <summary>Support methods for uncompressing zip files.</summary> 
    /// <remarks> 
    /// <para>This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g WinZip, InfoZip tools and compatible.</para> 
    /// <para>Encryption and multi volume ZipFile (span) are not supported.  Old compressions used by old PKZip 1.x are not supported.</para> 
    /// <para>Copyright (C) 1998 Gilles Vollant.  http://www.winimage.com/zLibDll/unzip.htm</para> 
    /// <para>C# wrapper by Gerry Shaw (gerry_shaw@yahoo.com).  http://www.organicbit.com/zip/</para> 
    /// </remarks> 
    internal sealed class ZipLib
    {
        // prevent instances of this class from being constructed 
        private ZipLib() { }

        /* 
            Create a zipfile. 
            pathname contain on Windows NT a filename like "c:\\zlib\\zlib111.zip" or on an Unix computer "zlib/zlib111.zip". 
            if the file pathname exist and append=1, the zip will be created at the end of the file. (useful if the file contain a self extractor code) 
            If the zipfile cannot be opened, the return value is NULL. 
            Else, the return value is a zipFile Handle, usable with other function of this zip package. 
        */
        /// <summary>Create a zip file.</summary> 
        [DllImport("zlib.dll", ExactSpelling = true, CharSet = CharSet.Ansi)]
        public static extern IntPtr zipOpen(string fileName, int append);

        /* 
            Open a file in the ZIP for writing. 
            filename : the filename in zip (if NULL, '-' without quote will be used 
            *zipfi contain supplemental information 
            if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local contains the extrafield data the the local header 
            if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global contains the extrafield data the the local header 
            if comment != NULL, comment contain the comment string 
            method contain the compression method (0 for store, Z_DEFLATED for deflate) 
            level contain the level of compression (can be Z_DEFAULT_COMPRESSION) 
        */
        /// <summary>Open a new zip entry for writing.</summary> 
        [DllImport("zlib.dll", ExactSpelling = true, CharSet = CharSet.Ansi)]
        unsafe public static extern int zipOpenNewFileInZip(IntPtr handle,
            string entryName,
            ZipFileEntryInfo* entryInfoPtr,
            byte[] extraField,
            uint extraFieldLength,
            byte[] extraFieldGlobal,
            uint extraFieldGlobalLength,
            string comment,
            int method,
            int level);

        /// <summary>Write data to the zip file.</summary> 
        [DllImport("zlib.dll")]
        public static extern int zipWriteInFileInZip(IntPtr handle, byte[] buffer, uint count);

        /// <summary>Close the current entry in the zip file.</summary> 
        [DllImport("zlib.dll")]
        public static extern int zipCloseFileInZip(IntPtr handle);

        /// <summary>Close the zip file.</summary> 
        [DllImport("zlib.dll", ExactSpelling = true, CharSet = CharSet.Ansi)]
        public static extern int zipClose(IntPtr handle, string comment);

        /// <summary>Opens a zip file for reading.</summary> 
        /// <param name="fileName">The name of the zip to open.  At this time only file names with ANSI (8 bit) characters are supported.</param> 
        /// <returns> 
        /// <para>A handle usable with other functions of the ZipLib class.</para> 
        /// <para>Otherwise IntPtr.Zero if the zip file could not e opened (file doen not exist or is not valid).</para> 
        /// </returns> 
        [DllImport("zlib.dll", ExactSpelling = true, CharSet = CharSet.Ansi)]
        public static extern IntPtr unzOpen(string fileName);

        /// <summary>Closes a zip file opened with unzipOpen.</summary> 
        /// <param name="handle">The zip file handle opened by <see cref="unzOpenCurrentFile"/>.</param> 
        /// <remarks>If there are files inside the zip file opened with <see cref="unzOpenCurrentFile"/> these files must be closed with <see cref="unzCloseCurrentFile"/> before call <c>unzClose</c>.</remarks> 
        /// <returns> 
        /// <para>Zero if there was no error.</para> 
        /// <para>Otherwise a value less than zero.  See <see cref="ErrorCode"/> for the specific reason.</para> 
        /// </returns> 
        [DllImport("zlib.dll")]
        public static extern int unzClose(IntPtr handle);

        /// <summary>Get global information about the zip file.</summary> 
        /// <param name="handle">The zip file handle opened by <see cref="unzOpenCurrentFile"/>.</param> 
        /// <param name="globalInfoPtr">An address of a <see cref="ZipFileInfo"/> struct to hold the information.  No preparation of the structure is needed.</param> 
        /// <returns> 
        /// <para>Zero if there was no error.</para> 
        /// <para>Otherwise a value less than zero.  See <see cref="ErrorCode"/> for the specific reason.</para> 
        /// </returns> 
        [DllImport("zlib.dll")]
        public unsafe static extern int unzGetGlobalInfo(IntPtr handle, ZipFileInfo* globalInfoPtr);

        /// <summary>Get the comment associated with the entire zip file.</summary> 
        /// <param name="handle">The zip file handle opened by <see cref="unzOpenCurrentFile"/></param> 
        /// <param name="commentBuffer">The buffer to hold the comment.</param> 
        /// <param name="commentBufferLength">The length of the buffer in bytes (8 bit characters).</param> 
        /// <returns> 
        /// <para>The number of characters in the comment if there was no error.</para> 
        /// <para>Otherwise a value less than zero.  See <see cref="ErrorCode"/> for the specific reason.</para> 
        /// </returns> 
        [DllImport("zlib.dll")]
        public static extern int unzGetGlobalComment(IntPtr handle, sbyte[] commentBuffer, uint commentBufferLength);

        /// <summary>Set the current file of the zip file to the first file.</summary> 
        /// <param name="handle">The zip file handle opened by <see cref="unzOpenCurrentFile"/>.</param> 
        /// <returns> 
        /// <para>Zero if there was no error.</para> 
        /// <para>Otherwise a value less than zero.  See <see cref="ErrorCode"/> for the specific reason.</para> 
        /// </returns> 
        [DllImport("zlib.dll")]
        public static extern int unzGoToFirstFile(IntPtr handle);

        /// <summary>Set the current file of the zip file to the next file.</summary> 
        /// <param name="handle">The zip file handle opened by <see cref="unzOpenCurrentFile"/>.</param> 
        /// <returns> 
        /// <para>Zero if there was no error.</para> 
        /// <para>Otherwise <see cref="ErrorCode.EndOfListOfFile"/> if there are no more entries.</para> 
        /// </returns> 
        [DllImport("zlib.dll")]
        public static extern int unzGoToNextFile(IntPtr handle);

        /// <summary>Try locate the entry in the zip file.</summary> 
        /// <param name="handle">The zip file handle opened by <see cref="unzOpenCurrentFile"/>.</param> 
        /// <param name="entryName">The name of the entry to look for.</param> 
        /// <param name="caseSensitivity">If 0 use the OS default.  If 1 use case sensitivity like strcmp, Unix style.  If 2 do not use case sensitivity like strcmpi, Windows style.</param> 
        /// <returns> 
        /// <para>Zero if there was no error.</para> 
        /// <para>Otherwise <see cref="ErrorCode.EndOfListOfFile"/> if there are no more entries.</para> 
        /// </returns> 
        [DllImport("zlib.dll", ExactSpelling = true, CharSet = CharSet.Ansi)]
        public static extern int unzLocateFile(IntPtr handle, string entryName, int caseSensitivity);

        /// <summary>Get information about the current entry in the zip file.</summary> 
        /// <param name="handle">The zip file handle opened by <see cref="unzOpenCurrentFile"/>.</param> 
        /// <param name="entryInfoPtr">A ZipEntryInfo struct to hold information about the entry or null.</param> 
        /// <param name="entryNameBuffer">An array of sbyte characters to hold the entry name or null.</param> 
        /// <param name="entryNameBufferLength">The length of the entryNameBuffer in bytes.</param> 
        /// <param name="extraField">An array to hold the extra field data for the entry or null.</param> 
        /// <param name="extraFieldLength">The length of the extraField array in bytes.</param> 
        /// <param name="commentBuffer">An array of sbyte characters to hold the entry name or null.</param> 
        /// <param name="commentBufferLength">The length of theh commentBuffer in bytes.</param> 
        /// <remarks> 
        ///   <para>If entryInfoPtr is not null the structure will contain information about the current file.</para> 
        ///   <para>If entryNameBuffer is not null the name of the entry will be copied into it.</para> 
        ///   <para>If extraField is not null the extra field data of the entry will be copied into it.</para> 
        ///   <para>If commentBuffer is not null the comment of the entry will be copied into it.</para> 
        /// </remarks> 
        /// <returns> 
        ///   <para>Zero if there was no error.</para> 
        ///   <para>Otherwise a value less than zero.  See <see cref="ErrorCode"/> for the specific reason.</para> 
        /// </returns> 
        [DllImport("zlib.dll", ExactSpelling = true, CharSet = CharSet.Ansi)]
        public unsafe static extern int unzGetCurrentFileInfo(IntPtr handle, ZipEntryInfo* entryInfoPtr,
            sbyte[] entryNameBuffer, uint entryNameBufferLength,
            byte[] extraField, uint extraFieldLength,
            sbyte[] commentBuffer, uint commentBufferLength);

        /// <summary>Open the zip file entry for reading.</summary> 
        /// <param name="handle">The zip file handle opened by <see cref="unzOpenCurrentFile"/>.</param> 
        /// <returns> 
        ///   <para>Zero if there was no error.</para> 
        ///   <para>Otherwise a value from <see cref="ErrorCode"/>.</para> 
        /// </returns> 
        [DllImport("zlib.dll")]
        public static extern int unzOpenCurrentFile(IntPtr handle);

        /// <summary>Close the file entry opened by <see cref="unzOpenCurrentFile"/>.</summary> 
        /// <param name="handle">The zip file handle opened by <see cref="unzOpenCurrentFile"/>.</param> 
        /// <returns> 
        ///   <para>Zero if there was no error.</para> 
        ///   <para>CrcError if the file was read but the Crc does not match.</para> 
        ///   <para>Otherwise a value from <see cref="ErrorCode"/>.</para> 
        /// </returns> 
        [DllImport("zlib.dll")]
        public static extern int unzCloseCurrentFile(IntPtr handle);

        /// <summary>Read bytes from the current zip file entry.</summary> 
        /// <param name="handle">The zip file handle opened by <see cref="unzOpenCurrentFile"/>.</param> 
        /// <param name="buffer">Buffer to store the uncompressed data into.</param> 
        /// <param name="count">Number of bytes to write from <paramref name="buffer"/>.</param> 
        /// <returns> 
        ///   <para>The number of byte copied if somes bytes are copied.</para> 
        ///   <para>Zero if the end of file was reached.</para> 
        ///   <para>Less than zero with error code if there is an error.  See <see cref="ErrorCode"/> for a list of possible error codes.</para> 
        /// </returns> 
        [DllImport("zlib.dll")]
        public static extern int unzReadCurrentFile(IntPtr handle, byte[] buffer, uint count);

        /// <summary>Give the current position in uncompressed data of the zip file entry currently opened.</summary> 
        /// <param name="handle">The zip file handle opened by <see cref="unzOpenCurrentFile"/>.</param> 
        /// <returns>The number of bytes into the uncompressed data read so far.</returns> 
        [DllImport("zlib.dll")]
        public static extern long unztell(IntPtr handle);

        /// <summary>Determine if the end of the zip file entry has been reached.</summary> 
        /// <param name="handle">The zip file handle opened by <see cref="unzOpenCurrentFile"/>.</param> 
        /// <returns> 
        ///   <para>One if the end of file was reached.</para> 
        ///   <para>Zero if elsewhere.</para> 
        /// </returns> 
        [DllImport("zlib.dll")]
        public static extern int unzeof(IntPtr handle);

        /// <summary>Converts a CLR string to a 8 bit ANSI array of characters.</summary> 
        /// <param name="str">The string to convert.</param> 
        /// <returns>A 8 bit ANSI array of characters.</returns> 
        public static sbyte[] StringToAnsi(string str)
        {
            int length = str.Length;
            sbyte[] chars = new sbyte[length + 1];
            for (int i = 0; i < length; i++)
            {
                chars[i] = (sbyte)str[i];
            }

            return chars;
        }

        /// <summary>Converst an 8 bit ANSI C style string to a CLR string.</summary> 
        /// <param name="chars">The array of a characters that holds the string.</param> 
        /// <returns>The CLR string representing the characters passed in.</returns> 
        public static string AnsiToString(sbyte[] chars)
        {
            int length = chars.Length;
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < length; i++)
            {
                builder.Append((char)chars[i]);
            }
            return builder.ToString();
        }
    }

    /// <summary>List of possible error codes.</summary> 
    internal enum ErrorCode : int
    {
        /// <summary>No error.</summary> 
        Ok = 0,

        /// <summary>Unknown error.</summary> 
        Error = -1,

        /// <summary>Last entry in directory reached.</summary> 
        EndOfListOfFile = -100,

        /// <summary>Parameter error.</summary> 
        ParameterError = -102,

        /// <summary>Zip file is invalid.</summary> 
        BadZipFile = -103,

        /// <summary>Internal program error.</summary> 
        InternalError = -104,

        /// <summary>Crc values do not match.</summary> 
        CrcError = -105
    }

    /// <summary>Global information about the zip file.</summary> 
    [StructLayout(LayoutKind.Sequential)]
    internal struct ZipFileInfo
    {
        /// <summary>The number of entries in the directory.</summary> 
        public UInt32 EntryCount;

        /// <summary>Length of zip file comment in bytes (8 bit characters).</summary> 
        public UInt32 CommentLength;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct ZipFileEntryInfo
    {
        public ZipDateTimeInfo DateTime;
        public UInt32 DosDate;
        public UInt32 InternalFileAttributes; // 2 bytes 
        public UInt32 ExternalFileAttributes; // 4 bytes 
    }

    /// <summary>Custom ZipLib date time structure.</summary> 
    [StructLayout(LayoutKind.Sequential)]
    internal struct ZipDateTimeInfo
    {
        /// <summary>Seconds after the minute - [0,59]</summary> 
        public UInt32 Seconds;

        /// <summary>Minutes after the hour - [0,59]</summary> 
        public UInt32 Minutes;

        /// <summary>Hours since midnight - [0,23]</summary> 
        public UInt32 Hours;

        /// <summary>Day of the month - [1,31]</summary> 
        public UInt32 Day;

        /// <summary>Months since January - [0,11]</summary> 
        public UInt32 Month;

        /// <summary>Years - [1980..2044]</summary> 
        public UInt32 Year;

        // implicit conversion from DateTime to ZipDateTimeInfo 
        public static implicit operator ZipDateTimeInfo(DateTime date)
        {
            ZipDateTimeInfo d;
            d.Seconds = (uint)date.Second;
            d.Minutes = (uint)date.Minute;
            d.Hours = (uint)date.Hour;
            d.Day = (uint)date.Day;
            d.Month = (uint)date.Month - 1;
            d.Year = (uint)date.Year;
            return d;
        }
    }

    /// <summary>Information stored in zip file directory about an entry.</summary> 
    [StructLayout(LayoutKind.Sequential)]
    internal struct ZipEntryInfo
    {
        // <summary>Version made by (2 bytes).</summary> 
        public UInt32 Version;

        /// <summary>Version needed to extract (2 bytes).</summary> 
        public UInt32 VersionNeeded;

        /// <summary>General purpose bit flag (2 bytes).</summary> 
        public UInt32 Flag;

        /// <summary>Compression method (2 bytes).</summary> 
        public UInt32 CompressionMethod;

        /// <summary>Last mod file date in Dos fmt (4 bytes).</summary> 
        public UInt32 DosDate;

        /// <summary>Crc-32 (4 bytes).</summary> 
        public UInt32 Crc;

        /// <summary>Compressed size (4 bytes).</summary> 
        public UInt32 CompressedSize;

        /// <summary>Uncompressed size (4 bytes).</summary> 
        public UInt32 UncompressedSize;

        /// <summary>Filename length (2 bytes).</summary> 
        public UInt32 FileNameLength;

        /// <summary>Extra field length (2 bytes).</summary> 
        public UInt32 ExtraFieldLength;

        /// <summary>File comment length (2 bytes).</summary> 
        public UInt32 CommentLength;

        /// <summary>Disk number start (2 bytes).</summary> 
        public UInt32 DiskStartNumber;

        /// <summary>Internal file attributes (2 bytes).</summary> 
        public UInt32 InternalFileAttributes;

        /// <summary>External file attributes (4 bytes).</summary> 
        public UInt32 ExternalFileAttributes;

        /// <summary>File modification date of entry.</summary> 
        public ZipDateTimeInfo DateTime;
    }
}

======================================================================

//ZipReader.cs 
using System;
using System.Collections;
using System.IO;
using System.Runtime.Serialization;

namespace OrganicBit.Zip
{
    /// <summary>Provides support for reading files in the ZIP file format. Includes support for both compressed and uncompressed entries.</summary> 
    /// <example>This example shows how to view the entries in a ZIP file. 
    /// <code> 
    /// public static void View(string zipFileName) { 
    ///     ZipReader reader = new ZipReader(zipFileName); 
    ///  
    ///     Console.WriteLine("Archive: {0} ({1} files)", zipFileName, reader.Entries.Count); 
    ///     Console.WriteLine(reader.Comment); 
    ///  
    ///     string format = "{0,8} {1,8} {2,5} {3,10} {4,5} {5}"; 
    ///     Console.WriteLine(format, " Length ", "  Size  ", "Ratio", "   Date   ", "Time ", "Name"); 
    ///     Console.WriteLine(format, "--------", "--------", "-----", "----------", "-----", "----"); 
    ///  
    ///     foreach (ZipEntry entry in reader.Entries) { 
    ///         if (!entry.IsDirectory) { 
    ///             Console.WriteLine(format, 
    ///                 entry.Length, 
    ///                 entry.CompressedLength, 
    ///                 entry.Ratio.ToString("P0"), 
    ///                 entry.ModifiedTime.ToString("yyyy-MM-dd"), 
    ///                 entry.ModifiedTime.ToString("hh:mm"), 
    ///                 entry.Name); 
    ///         } 
    ///     } 
    ///     reader.Close(); 
    /// } 
    /// </code> 
    /// </example> 
    /// <example>This example shows how to extract files from a ZIP file. 
    /// <code> 
    /// public static void Extract(string zipFileName) { 
    ///     ZipReader reader = new ZipReader(zipFileName); 
    ///     Console.WriteLine("Archive: {0}", zipFileName); 
    ///     Console.WriteLine(reader.Comment); 
    ///  
    ///     // buffer to hold temp bytes 
    ///     byte[] buffer = new byte[4096]; 
    ///     int byteCount; 
    ///  
    ///     // Get the zipped entries 
    ///     while (reader.MoveNext()) { 
    ///         ZipEntry entry = reader.Current; 
    ///  
    ///         if (entry.IsDirectory) { 
    ///             Directory.CreateDirectory(entry.Name); 
    ///         } else { 
    ///             Console.Write("  {0}", entry.Name); 
    ///  
    ///             // create output stream 
    ///             FileStream writer = File.Open(entry.Name, FileMode.Create); 
    ///  
    ///             // write uncompressed data 
    ///             while ((byteCount = reader.Read(buffer, 0, buffer.Length)) > 0) { 
    ///                 Console.Write("."); 
    ///                 writer.Write(buffer, 0, byteCount); 
    ///             } 
    ///             writer.Close(); 
    ///             Console.WriteLine(); 
    ///         } 
    ///     } 
    ///     reader.Close(); 
    /// } 
    /// </code> 
    /// </example> 
    public class ZipReader : IEnumerator, IDisposable
    {

        /// <summary>ZipFile handle to read data from.</summary> 
        IntPtr _handle = IntPtr.Zero;

        /// <summary>Name of zip file.</summary> 
        string _fileName = null;

        /// <summary>Contents of zip file directory.</summary> 
        ZipEntryCollection _entries = null;

        /// <summary>Global zip file comment.</summary> 
        string _comment = null;

        /// <summary>True if an entry is open for reading.</summary> 
        bool _entryOpen = false;

        /// <summary>Current zip entry open for reading.</summary> 
        ZipEntry _current = null;

        /// <summary>Initializes a instance of the <see cref="ZipReader"/> class for reading the zip file with the given name.</summary> 
        /// <param name="fileName">The name of zip file that will be read.</param> 
        public ZipReader(string fileName)
        {
            _fileName = fileName;
            _handle = ZipLib.unzOpen(fileName);
            if (_handle == IntPtr.Zero)
            {
                string msg = String.Format("Could not open zip file '{0}'.", fileName);
                throw new ZipException(msg);
            }
        }

        /// <summary>Cleans up the resources used by this zip file.</summary> 
        ~ZipReader()
        {
            CloseFile();
        }

        /// <remarks>Dispose is synonym for Close.</remarks> 
        void IDisposable.Dispose()
        {
            Close();
        }

        /// <summary>Closes the zip file and releases any resources.</summary> 
        public void Close()
        {
            // Free unmanaged resources. 
            CloseFile();

            // If base type implements IDisposable we would call it here. 

            // Request the system not call the finalizer method for this object. 
            GC.SuppressFinalize(this);
        }

        /// <summary>Gets the name of the zip file that was passed to the constructor.</summary> 
        public string Name
        {
            get { return _fileName; }
        }

        /// <summary>Gets the global comment for the zip file.</summary> 
        public string Comment
        {
            get
            {
                if (_comment == null)
                {
                    ZipFileInfo info;
                    int result = 0;
                    unsafe
                    {
                        result = ZipLib.unzGetGlobalInfo(_handle, &info);
                    }
                    if (result < 0)
                    {
                        string msg = String.Format("Could not read comment from zip file '{0}'.", Name);
                        throw new ZipException(msg);
                    }

                    sbyte[] buffer = new sbyte[info.CommentLength];
                    result = ZipLib.unzGetGlobalComment(_handle, buffer, (uint)buffer.Length);
                    if (result < 0)
                    {
                        string msg = String.Format("Could not read comment from zip file '{0}'.", Name);
                        throw new ZipException(msg);
                    }
                    _comment = ZipLib.AnsiToString(buffer);
                }
                return _comment;
            }
        }

        /// <summary>Gets a <see cref="ZipEntryCollection"/> object that contains all the entries in the zip file directory.</summary> 
        public ZipEntryCollection Entries
        {
            get
            {
                if (_entries == null)
                {
                    _entries = new ZipEntryCollection();

                    int result = ZipLib.unzGoToFirstFile(_handle);
                    while (result == 0)
                    {
                        ZipEntry entry = new ZipEntry(_handle);
                        _entries.Add(entry);
                        result = ZipLib.unzGoToNextFile(_handle);
                    }
                }
                return _entries;
            }
        }

        object IEnumerator.Current
        {
            get
            {
                return _current;
            }
        }

        /// <summary>Gets the current entry in the zip file..</summary> 
        public ZipEntry Current
        {
            get
            {
                return _current;
            }
        }

        /// <summary>Advances the enumerator to the next element of the collection.</summary> 
        /// <summary>Sets <see cref="Current"/> to the next zip entry.</summary> 
        /// <returns><c>true</c> if the next entry is not <c>null</c>; otherwise <c>false</c>.</returns> 
        public bool MoveNext()
        {
            // close any open entry 
            CloseEntry();

            int result;
            if (_current == null)
            {
                result = ZipLib.unzGoToFirstFile(_handle);
            }
            else
            {
                result = ZipLib.unzGoToNextFile(_handle);
            }
            if (result < 0)
            {
                // last entry found - not an exceptional case 
                _current = null;
            }
            else
            {
                // entry found 
                OpenEntry();
            }

            return (_current != null);
        }

        /// <summary>Move to just before the first entry in the zip directory.</summary> 
        public void Reset()
        {
            CloseEntry();
            _current = null;
        }

        /// <summary>Seek to the specified entry.</summary> 
        /// <param name="entryName">The name of the entry to seek to.</param> 
        public void Seek(string entryName)
        {
            CloseEntry();
            int result = ZipLib.unzLocateFile(_handle, entryName, 0);
            if (result < 0)
            {
                string msg = String.Format("Could not locate entry named '{0}'.", entryName);
                throw new ZipException(msg);
            }
            OpenEntry();
        }

        private void OpenEntry()
        {
            _current = new ZipEntry(_handle);
            int result = ZipLib.unzOpenCurrentFile(_handle);
            if (result < 0)
            {
                _current = null;
                throw new ZipException("Could not open entry for reading.");
            }
            _entryOpen = true;
        }

        /// <summary>Uncompress a block of bytes from the current zip entry and writes the data in a given buffer.</summary> 
        /// <param name="buffer">The array to write data into.</param> 
        /// <param name="index">The byte offset in <paramref name="buffer"/> at which to begin writing.</param> 
        /// <param name="count">The maximum number of bytes to read.</param> 
        public int Read(byte[] buffer, int index, int count)
        {
            if (index != 0)
            {
                throw new ArgumentException("index", "Only index values of zero currently supported.");
            }
            int bytesRead = ZipLib.unzReadCurrentFile(_handle, buffer, (uint)count);
            if (bytesRead < 0)
            {
                throw new ZipException("Error reading zip entry.");
            }
            return bytesRead;
        }

        private void CloseEntry()
        {
            if (_entryOpen)
            {
                int result = ZipLib.unzCloseCurrentFile(_handle);
                if (result < 0)
                {
                    switch ((ErrorCode)result)
                    {
                        case ErrorCode.CrcError:
                            throw new ZipException("All the file was read but the CRC did not match.");

                        default:
                            throw new ZipException("Could not close zip entry.");
                    }
                }
                _entryOpen = false;
            }
        }

        private void CloseFile()
        {
            if (_handle != IntPtr.Zero)
            {
                CloseEntry();
                int result = ZipLib.unzClose(_handle);
                if (result < 0)
                {
                    throw new ZipException("Could not close zip file.");
                }
                _handle = IntPtr.Zero;
            }
        }
    }
}

======================================================================

//ZipWriter.cs 
using System;
using System.IO;
using System.Runtime.Serialization;

namespace OrganicBit.Zip
{

    /// <summary>Provides support for writing files in the ZIP file format. Includes support for both compressed and uncompressed entries.</summary> 
    /// <example>This example shows how to create a ZIP file. 
    /// <code> 
    /// public static void Add(string zipFileName, string[] entryPatterns) { 
    ///     string currentDirectory = Directory.GetCurrentDirectory(); 
    ///     Console.WriteLine("Creating {0}", zipFileName); 
    ///  
    ///     ZipWriter writer = new ZipWriter(zipFileName); 
    ///  
    ///     // buffer to hold temp bytes 
    ///     byte[] buffer = new byte[4096]; 
    ///     int byteCount; 
    ///  
    ///     // add files to archive 
    ///     foreach (string pattern in entryPatterns) { 
    ///         foreach (string path in Directory.GetFiles(currentDirectory, pattern)) { 
    ///             string fileName = Path.GetFileName(path); 
    ///             Console.Write("Adding {0}", fileName); 
    ///  
    ///             ZipEntry entry = new ZipEntry(fileName); 
    ///             entry.ModifiedTime = File.GetLastWriteTime(fileName); 
    ///             entry.Comment = "local file comment"; 
    ///  
    ///             writer.AddEntry(entry); 
    ///  
    ///             FileStream reader = File.OpenRead(entry.Name); 
    ///             while ((byteCount = reader.Read(buffer, 0, buffer.Length)) > 0) { 
    ///                 Console.Write("."); 
    ///                 writer.Write(buffer, 0, byteCount); 
    ///             } 
    ///             reader.Close(); 
    ///             Console.WriteLine(); 
    ///         } 
    ///     } 
    ///  
    ///     writer.Close(); 
    /// } 
    /// </code> 
    /// </example> 
    public class ZipWriter : IDisposable
    {

        /// <summary>Name of the zip file.</summary> 
        string _fileName;

        /// <summary>Zip file global comment.</summary> 
        string _comment = "";

        /// <summary>True if currently writing a new zip file entry.</summary> 
        bool _entryOpen = false;

        /// <summary>Zip file handle.</summary> 
        IntPtr _handle = IntPtr.Zero;

        /// <summary>Initializes a new instance fo the <see cref="ZipWriter"/> class with a specified file name.  Any Existing file will be overwritten.</summary> 
        /// <param name="fileName">The name of the zip file to create.</param> 
        public ZipWriter(string fileName)
        {
            _fileName = fileName;

            _handle = ZipLib.zipOpen(fileName, 0);
            if (_handle == IntPtr.Zero)
            {
                string msg = String.Format("Could not open zip file '{0}' for writing.", fileName);
                throw new ZipException(msg);
            }
        }

        /// <summary>Cleans up the resources used by this zip file.</summary> 
        ~ZipWriter()
        {
            CloseFile();
        }

        /// <remarks>Dispose is synonym for Close.</remarks> 
        void IDisposable.Dispose()
        {
            Close();
        }

        /// <summary>Closes the zip file and releases any resources.</summary> 
        public void Close()
        {
            // Free unmanaged resources. 
            CloseFile();

            // If base type implements IDisposable we would call it here. 

            // Request the system not call the finalizer method for this object. 
            GC.SuppressFinalize(this);
        }

        /// <summary>Gets the name of the zip file.</summary> 
        public string Name
        {
            get
            {
                return _fileName;
            }
        }

        /// <summary>Gets and sets the zip file comment.</summary> 
        public string Comment
        {
            get { return _comment; }
            set { _comment = value; }
        }

        /// <summary>Creates a new zip entry in the directory and positions the stream to the start of the entry data.</summary> 
        /// <param name="entry">The zip entry to be written.</param> 
        /// <remarks>Closes the current entry if still active.</remarks> 
        public void AddEntry(ZipEntry entry)
        {
            ZipFileEntryInfo info;
            info.DateTime = entry.ModifiedTime;

            int result;
            unsafe
            {
                byte[] extra = null;
                uint extraLength = 0;
                if (entry.ExtraField != null)
                {
                    extra = entry.ExtraField;
                    extraLength = (uint)entry.ExtraField.Length;
                }

                result = ZipLib.zipOpenNewFileInZip(
                    _handle,
                    entry.Name,
                    &info,
                    extra,
                    extraLength,
                    null, 0,
                    entry.Comment,
                    (int)entry.Method,
                    entry.Level);
            }
            _entryOpen = true;
        }

        /// <summary>Compress a block of bytes from the given buffer and writes them into the current zip entry.</summary> 
        /// <param name="buffer">The array to read data from.</param> 
        /// <param name="index">The byte offset in <paramref name="buffer"/> at which to begin reading.</param> 
        /// <param name="count">The maximum number of bytes to write.</param> 
        public void Write(byte[] buffer, int index, int count)
        {
            int result = ZipLib.zipWriteInFileInZip(_handle, buffer, (uint)count);
        }

        private void CloseEntry()
        {
            if (_entryOpen)
            {
                int result = ZipLib.zipCloseFileInZip(_handle);
                _entryOpen = false;
            }
        }

        void CloseFile()
        {
            if (_handle != IntPtr.Zero)
            {
                CloseEntry();
                int result = ZipLib.zipClose(_handle, _comment);
                if (result < 0)
                {
                    throw new ZipException("Could not close zip file.");
                }
                _handle = IntPtr.Zero;
            }
        }
    }
}

nightmoon
等级:青蜂侠
财产:10520
经验:8390
魅力:2037
注册:2002-8-24
登录:2003-4-21
文章:464
签定:辽宁省沈阳市

Re:用 .Net 实现 Zip
good


WS.NET
等级:侠圣
财产:11120
经验:82342
魅力:7480
注册:2002-9-13
登录:2003-4-23
文章:2468
签定:北京市联通

Re:用 .Net 实现 Zip
好文章!
以前见过VC++的,现在C#的也出来了,太棒啦!
这么长,得赶紧试试。。。

Contributors: FHL