michael_wp原创:用.net实现zip----5
发表于:2007-06-30来源:作者:点击数:
标签:
//ZipReader.cs using System; using System.Collections; using System.Runtime.Serialization; namespace OrganicBit.Zip { /// summaryProvides support for reading files in the ZIP file format. Includes support for both compressed and uncompresse
//ZipReader.cs
using System;
using System.Collections;
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;
}
}
}
}
原文转自:http://www.ltesting.net