Está en la página 1de 9

La clase ZipUtil

//-----------------------------------------------------------------------
-------
// ZipUtil
(16/Dic/02)
// utilidad para comprimir/descomprimir ficheros zips
// usando SharpZipLib.dll
//
// ©Guillermo 'guille' Som, 2002
//-----------------------------------------------------------------------
-------
using System;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksums;
using System.IO;

public class ZipUtil


{
public void Comprimir(string directorio, string filtro, string
zipFic, bool crearAuto)
{
// comprimir los ficheros del directorio indicado
// y guardarlo en el zip
// en filtro se indicará el filtro a usar para seleccionar los
ficheros del directorio
// si directorio es una cadena vacía, filtro será el fichero a
comprimir (sólo ese)
// si crearAuto = True, zipfile será el directorio en el que se
guardará
// y se generará automáticamente el nombre con la fecha y hora
actual
//
string[] fileNames = new string[1];
if(directorio == "")
{
fileNames[0] = filtro;
}
else
{
fileNames = Directory.GetFiles(directorio, filtro);
}
// llamar a la versión sobrecargada que recibe un array
Comprimir(fileNames, zipFic, crearAuto);
//
}
//
public void Comprimir(string[] fileNames, string zipFic, bool
crearAuto)
{
// comprimir los ficheros del array en el zip indicado
// si crearAuto = True, zipfile será el directorio en el que se
guardará
// y se generará automáticamente el nombre con la fecha y hora
actual
Crc32 objCrc32 = new Crc32();
ZipOutputStream strmZipOutputStream;
//
if( zipFic == "" )
{
zipFic = ".";
crearAuto = true;
}
if( crearAuto )
{
// si hay que crear el nombre del fichero
// éste será el path indicado y la fecha actual
zipFic += @"\ZIP" + DateTime.Now.ToString("yyMMddHHmmss") +
".zip";
}
strmZipOutputStream = new ZipOutputStream(File.Create(zipFic));
// Compression Level: 0-9
// 0: no(Compression)
// 9: maximum compression
strmZipOutputStream.SetLevel(6);
//
foreach(string strFile in fileNames)
{
FileStream strmFile = File.OpenRead(strFile);
byte[] abyBuffer = new
byte[(Convert.ToInt32(strmFile.Length))];
//
strmFile.Read(abyBuffer, 0, abyBuffer.Length);
//
// //-------------------------------------------------------
------
// // para guardar sin el primer path
// string sFile = strFile;
// int i = sFile.IndexOf(@"\");
// if( i > -1)
// {
// sFile = sFile.Substring(i + 1).TrimStart();
// }
// //-------------------------------------------------------
------
// //
// //-------------------------------------------------------
------
// // para guardar sólo el nombre del fichero
// // esto sólo se debe hacer si no se procesan directorios
// // que puedan contener nombres repetidos
// string sFile = Path.GetFileName(strFile);
// ZipEntry theEntry = new ZipEntry(sFile);
// //-------------------------------------------------------
------
//
// se guarda con el path completo
ZipEntry theEntry = new ZipEntry(strFile);
//
// guardar la fecha y hora de la última modificación
FileInfo fi = new FileInfo(strFile);
theEntry.DateTime = fi.LastWriteTime;
//theEntry.DateTime = DateTime.Now;
//
theEntry.Size = strmFile.Length;
strmFile.Close();
objCrc32.Reset();
objCrc32.Update(abyBuffer);
theEntry.Crc = objCrc32.Value;
strmZipOutputStream.PutNextEntry(theEntry);
strmZipOutputStream.Write(abyBuffer, 0, abyBuffer.Length);
}
strmZipOutputStream.Finish();
strmZipOutputStream.Close();
}
//
public void Descomprimir(string directorio, string zipFic, bool
eliminar, bool renombrar)
{
// descomprimir el contenido de zipFic en el directorio indicado.
// si zipFic no tiene la extensión .zip, se entenderá que es un
directorio y
// se procesará el primer fichero .zip de ese directorio.
// si eliminar es True se eliminará ese fichero zip después de
descomprimirlo.
// si renombrar es True se añadirá al final .descomprimido
if( !zipFic.ToLower().EndsWith(".zip") )
{
zipFic = Directory.GetFiles(zipFic, "*.zip")[0];
}
// si no se ha indicado el directorio, usar el actual
if( directorio == "" ) directorio = ".";
//
ZipInputStream z = new ZipInputStream(File.OpenRead(zipFic));
ZipEntry theEntry;
//
do
{
theEntry = z.GetNextEntry();
if( !(theEntry == null) )
{
string fileName = directorio + @"\" +
Path.GetFileName(theEntry.Name);
//
// dará error si no existe el path
FileStream streamWriter;
try
{
streamWriter = File.Create(fileName);
}
catch (DirectoryNotFoundException ex)
{

Directory.CreateDirectory(Path.GetDirectoryName(fileName));
streamWriter = File.Create(fileName);
}
//
int size = 2048;
byte[] data = new byte[2048];
do
{
size = z.Read(data, 0, data.Length);
if( (size > 0) )
{
streamWriter.Write(data, 0, size);
}
else
{
break;
}
}while(true);
streamWriter.Close();
}
else
{
break;
}
}while(true);
z.Close();
//
// cuando se hayan extraído los ficheros, renombrarlo
if( renombrar )
{
File.Copy(zipFic, zipFic + ".descomprimido");
}
if( eliminar )
{
File.Delete(zipFic);
}
}
//
public ZipEntry[] Contenido(string zipFic)
{
// devuelve el contenido del zip indicado
ZipInputStream strmZipInputStream = new
ZipInputStream(File.OpenRead(zipFic));
ZipEntry objEntry;
ZipEntry[] files = new ZipEntry[1];
int n = -1;
//
while ((objEntry = strmZipInputStream.GetNextEntry()) != null)
{
n = n + 1;
// hacer una copia de files
// para añadir el nuevo elemento
// ¡con lo fácil que es usar ReDim Preserve!
if(n > 0)
{
ZipEntry[] files2 = new ZipEntry[n + 1];
Array.Copy(files, files2, n);
files2[n] = objEntry;
files = new ZipEntry[n + 1];
Array.Copy(files2, files, n + 1);
files2 = null;
}
else
{
files[0] = objEntry;
}
}
strmZipInputStream.Close();
//
return files;
}
}

El formulario de ejemplo
//-----------------------------------------------------------------------
-------
// Utilidad para comprimir/descomprimir ficheros
(16/Dic/02)
// usando SharpZipLib.dll
//
// ©Guillermo 'guille' Som, 2002
//-----------------------------------------------------------------------
-------
// En este ejemplo utilizo esta constante para indicar si el código
// es compatible con el VS 2002 o para versiones posteriores
// En el caso de las versiones posteriores, se usan los bucles
// con la variable declarada junto al For o ForEach y
// para seleccionar directorios se usa la nueva clase FolderBrowserDialog
#define VS2002

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;

///
/// Descripción breve de Form1.
///
public class fZipTest : System.Windows.Forms.Form
{
//
//...
//
private bool iniciando = true;
private cLine3DEx linea3D;
private OpenFileDialog openFD = new OpenFileDialog();
private ZipUtil zUtil = new ZipUtil();
//
private void fZipTest_Load(System.Object sender, System.EventArgs
e)
{
linea3D = new cLine3DEx(linea1, linea2, this);
linea3D.AdjustWidth = true;
//
zipFicTextBox.Text = "";
unZipDirTextBox.Text = "";
zipButton.Enabled = false;
//
iniciando = false;
}

private void fZipTest_Resize(object sender, System.EventArgs e)


{
if( !iniciando )
{
if( WindowState != FormWindowState.Minimized )
{
linea3D.Resize();
}
}
}

private void cerrarButton_Click(System.Object sender,


System.EventArgs e)
{
this.Close();
}

private void examinarButton_Click(System.Object sender,


System.EventArgs e)
{
// seleccionar el fichero ZIP con el que se va a trabajar
openFD.Title = "Selecciona el fichero ZIP";
openFD.Filter = "Ficheros ZIPs (*.zip)|*.zip|Todos los ficheros
(*.*)|*.*";
openFD.FileName = this.zipFicTextBox.Text;
openFD.Multiselect = false;
// para que se puede indicar un fichero que no existe
openFD.CheckFileExists = false;
if( openFD.ShowDialog() == DialogResult.OK )
{
zipFicTextBox.Text = openFD.FileName;
}

private void addButton_Click(System.Object sender, System.EventArgs


e)
{
// añadir ficheros a la lista
openFD.Title = "Selecciona los ficheros a comprimir";
openFD.Filter = "Código|*.vb*;*.c*;*.pas;*.h*;*.bas;*.pr*;|Todos
los ficheros (*.*)|*.*";
openFD.Multiselect = true;
if( openFD.ShowDialog() == DialogResult.OK )
{
files2List(openFD.FileNames);
}
}

private void mostrarButton_Click(System.Object sender,


System.EventArgs e)
{
// mostrar el contenido del zip indicado
ZipEntry[] files = zUtil.Contenido(zipFicTextBox.Text);
//
this.Cursor = Cursors.WaitCursor;
listaFic.Items.Clear();
//
foreach(ZipEntry theEntry in files)
{
if(theEntry != null)
{
ListViewItem lvi = listaFic.Items.Add(theEntry.Name);
lvi.SubItems.Add(theEntry.Size.ToString("#,##0"));
}
}
zipButton.Enabled = listaFic.Items.Count > 0;
this.Cursor = Cursors.Default;
}

private void zipFicTextBox_Enter(object sender, System.EventArgs e)


{
zipFicTextBox.SelectAll();
}

private void zipFicTextBox_TextChanged(System.Object sender,


System.EventArgs e)
{
// si no existe, deshabilitar mostrar
try
{
mostrarButton.Enabled = File.Exists(zipFicTextBox.Text);
}
catch //(Exception ex )
{

mostrarButton.Enabled = false;
}
unZipButton.Enabled = mostrarButton.Enabled;
}

private void zipFicTextBox_DragOver(object sender,


System.Windows.Forms.DragEventArgs e)
{ //
if( e.Data.GetDataPresent("FileDrop") == true )
{
e.Effect = DragDropEffects.Copy;
}
}

private void zipFicTextBox_DragDrop(object sender,


System.Windows.Forms.DragEventArgs e)
{
if( e.Data.GetDataPresent("FileDrop") == true )
{
zipFicTextBox.Text = ((string[])(e.Data.GetData("FileDrop",
true)))[0]; }
}

private void listaFic_DragDrop(object sender,


System.Windows.Forms.DragEventArgs e)
{
if( e.Data.GetDataPresent("FileDrop") == true )
{
files2List(( (string[])(e.Data.GetData("FileDrop", true)) ));
}
}

private void files2List(string[] files)


{
FileInfo fi;
//
foreach(string s in files)
{
fi = new FileInfo(s);

listaFic.Items.Add(s).SubItems.Add(fi.Length.ToString("#,##0"));

}
zipButton.Enabled = listaFic.Items.Count > 0;
}

private void unZipButton_Click(System.Object sender,


System.EventArgs e)
{
// descomprimir el contenido del fichero en el directorio
indicado
this.Cursor = Cursors.WaitCursor;
zUtil.Descomprimir(unZipDirTextBox.Text, zipFicTextBox.Text,
false, false);
this.Cursor = Cursors.Default;
}

private void zipButton_Click(System.Object sender, System.EventArgs


e)
{
// comprimir los ficheros de la lista en el zip indicado
int n = this.listaFic.Items.Count - 1;
string[] files = new string[(n + 1)];
//
this.Cursor = Cursors.WaitCursor;
//
for(int i = 0; i <= n; i++)
{
files[i] = listaFic.Items[i].Text;
}
zUtil.Comprimir(files, zipFicTextBox.Text, false);
zipFicTextBox_TextChanged(zipFicTextBox, new EventArgs());
this.Cursor = Cursors.Default;
}
private void examinarDirButton_Click(System.Object sender,
System.EventArgs e)
{
// usar este código para VS2002
openFD.Title = "Selecciona el directorio para descomprimir los
ficheros";
openFD.Filter = "Todos los ficheros (*.*)|*.*";
openFD.InitialDirectory = unZipDirTextBox.Text;
openFD.Multiselect = false;
// para que se puede indicar un fichero que no existe
openFD.CheckFileExists = false;
if( openFD.ShowDialog() == DialogResult.OK )
{
unZipDirTextBox.Text =
Path.GetDirectoryName(openFD.FileName);
}
// //
// // esto sólo es válido para VS2003
// //
// FolderBrowserDialog bf = new FolderBrowserDialog();
// //
// bf.Description = "Selecciona el directorio para descomprimir
los ficheros";
// bf.RootFolder = Environment.SpecialFolder.MyComputer;
// bf.ShowNewFolderButton = true;
// bf.SelectedPath = unZipDirTextBox.Text;
// if( bf.ShowDialog == DialogResult.OK ){
// unZipDirTextBox.Text = bf.SelectedPath;
// }
// //
// //
// //
}

private void listaFic_KeyUp(object sender,


System.Windows.Forms.KeyEventArgs e)
{
// eliminar los elementos seleccionados
if( e.KeyCode == Keys.Delete )
{
quitarButton_Click(sender, new EventArgs());
}
}

private void quitarButton_Click(System.Object sender,


System.EventArgs e)
{
// eliminar de la lista los elementos seleccionados
//
for(int i = listaFic.SelectedIndices.Count - 1; i >= 0; i--)
{
listaFic.Items.RemoveAt(listaFic.SelectedIndices[i]);
}
this.zipButton.Enabled = listaFic.Items.Count > 0;
}
}

También podría gustarte