Picacodigos
« Los de siempre, como siempre
|
Mas Reciente
|
Apellidos aleatorios (y falsos) »
Comprimiendo y descomprimiendo ficheros ZIP
Published 91 weeks, 5 days ago
Thu
Jan
04
2007
Para comprimir y descomprimir ficheros en formato ZIP tenemos una herramienta muy valiosa a nuestra disposición: la excelente librería
SharpZipLib
, creada por IC#Code, el mismo grupo de desarrolladores que nos han proporcionado el excelente IDE Open Source para C#
SharpDevelop
, del que ya os he hablado otras veces.
Lo primero que tenemos que hacer, por lo tanto, es descargar dicha librería a nuestro sistema. Una vez hecho esto, debemos incluirla como referencia en el proyecto de Visual Studio en el que vayamos a usarla. Si creemos que vamos a usarla con relativa frecuencia, lo más cómodo es instalarla en el GAC. Para ello, abrimos la
Ventana de comandos de Visual Studio 2005
, que encontraremos bajo
Herramientas
del grupo del menú de Inicio
Visual Studio 2005
. Cuando lo ejecutamos, se abre una consola que deberemos dirigir a la ruta donde hayamos descargado la librería ICSharpCode.SharpZipLib.dll (por comodidad, yo la tengo en una carpeta propia en C:\Archivos de Programa) y una vez situados ahí escribimos el siguiente comando:
gacutil /i ICSharpCode.SharpZipLib.dll
De esta manera añadimos la librería a la caché global de ensamblados para Visual Studio.
Tanto si añadimos la librería al GAC como si no, debemos referenciarla en nuestro proyecto. Para ello, ya sabéis, una vez creado nuestro proyecto (de consola, Windows o Web) elegimos el menú
Proyecto
,
Añadir Referencia
y elegimos la librería en el cuadro de diálogo que nos aparece: en la solapa llamada
.NET
si hemos incluido la librería en el GAC, o podemos buscarla mediante la solapa
Examinar
. Una vez incluida la referencia, incluimos la línea
using
ICSharpCode.SharpZipLib.Zip
;
en nuestro código y ya estamos listos.
Una última aclaración antes de meternos en faena: para hacer más simple este artículo he decidido que los ejemplos de código incluidos funcionen en la consola y he dado por supuestas varias cosas, como rutas y nombres de ficheros. Si quieres que el código fuente te funcione no te limites a cortarlo y pegarlo, debes adaptarlo a las rutas y nombres de ficheros existentes en tu sistema.
Listar Contenido de Ficheros
Vamos a ver primero cómo listar el contenido de un fichero ZIP. Para ello, nos limitamos a declarar una variable llamada
zip
de tipo
ZipFile
. Nótese que SharpZipLib hace que un ZipFile esté compuesto de objetos ZipEntry, no de ficheros ni de líneas ni de ninguna otra cosa por el estilo. El objeto ZipEntry va a representar cualquiera de las entidades que pueden estar contenidas en un fichero ZIP, sean un fichero o un directorio. Una vez sabido esto, nos recorremos las entradas del fichero ZIP mediante un bucle
foreach
y sencillamente mostramos el nombre de la entrada en la consola:
private static void
ListarContenidoZip(
string
sFile)
{
ZipFile zip
= new
ZipFile(File.OpenRead(sFile))
;
foreach
(ZipEntry entry
in
zip)
{
Console.WriteLine(entry.Name)
;
}
}
Colorized by:
CarlosAg.CodeColorizer
Descomprimir Ficheros
La trama se complica. Para descomprimir un fichero ZIP lo abriremos como un objeto
ZipInputStream
, recorremos sus entradas mediante el método
GetNextEntry()
y guardaremos el contenido binario de cada entrada en un array de bytes. Dicho array alimentará a un objeto StreamWriter, con el cual crearemos el nuevo fichero, que será una copia exacta de los datos binarios de la entrada del fichero ZIP.
private static void
DescomprimirZip(
string
sFile)
{
ZipInputStream zipIn
= new
ZipInputStream(File.OpenRead(sFile))
;
ZipEntry entry
;
while
((entry
=
zipIn.GetNextEntry()) !
= null
)
{
FileStream streamWriter
=
File.Create(
@"C:\Temp\"
+ entry.Name)
;
long
size
=
entry.Size
;
byte
[] data
= new byte
[size]
;
while
(
true
)
{
size
=
zipIn.Read(data,
0
, data.Length)
;
if
(size >
0
) streamWriter.Write(data,
0
, (
int
) size)
;
else break;
}
streamWriter.Close()
;
}
Console.WriteLine(
"Hecho!!"
)
;
}
Colorized by:
CarlosAg.CodeColorizer
Comprimir ficheros
Para comprimir ficheros, usaremos un objeto similar al anterior pero de propósito opuesto, el
ZipOutputStream
. Para mantener la sencillez del ejemplo, he supuesto que queremos comprimir
todos
los ficheros existentes en la ruta pasada en el parámetro
sRuta
. Por lo tanto, nos recorremos todos los ficheros existentes en dicha ruta, creamos un nuevo objeto
ZipEntry
, obtenemos cierta información mediante
FileInfo
(podríamos haber incluido chequeo de CRC, pero quería mantener el ejemplo sencillo) para asignar dicha información a la nueva entrada, y añadimos la entrada al objeto
ZipOutputStream
mediante el método
PutNextEntry
. Ojo, esto crearía una entrada vacía: para realmente introducir los datos que contiene el fichero (sea un fichero de texto o un binario cualquiera) debemos leer sus datos binarios mediante un
FileStream
como en el ejemplo anterior y entonces invocar el método
Write
del
ZipOutputStream
para guardar dichos datos binarios en la última entrada del stream de salida Zip. Una vez recorridos e incluidos todos los ficheros, terminamos y cerramos el objeto
ZipOutputStream
.
private static void
ComprimirZip(
string
sRuta)
{
ZipOutputStream zipOut
= new
ZipOutputStream(File.Create(
@"C:\Temp\prueba.zip"
))
;
foreach
(
string
fName
in
Directory.GetFiles(sRuta))
{
FileInfo fi
= new
FileInfo(fName)
;
ZipEntry entry
= new
ZipEntry(fi.Name)
;
FileStream sReader
=
File.OpenRead(fName)
;
byte
[] buff
= new byte
[Convert.ToInt32(sReader.Length)]
;
sReader.Read(buff,
0
, (
int
) sReader.Length)
;
entry.DateTime
=
fi.LastWriteTime
;
entry.Size
=
sReader.Length
;
sReader.Close()
;
zipOut.PutNextEntry(entry)
;
zipOut.Write(buff,
0
, buff.Length)
;
}
zipOut.Finish()
;
zipOut.Close()
;
}
Colorized by:
CarlosAg.CodeColorizer
Y esto concluye esta pequeña introducción a
SharpZipLib
. IC#Code mantiene un
excelente foro
(en inglés) en el que podréis ver más ejemplo de código y más dudas resueltas.
Actualización 5/01/2007
.- Jugando un poco con la librería y el Examinador de Objetos de VS 2005, me encuentro con una clase llamada FastZip. Hmmmm. Pues sí, es lo que parece: una clase
wrapper
para facilitar la compresión y descompresión de archivos mediante SharpZipLib. Por ejemplo, para descomprimir un fichero es tan simple como esto:
private static void
DescomprimirZipFast(
string
sFile)
{
FastZip fZip
= new
FastZip()
;
fZip.ExtractZip(sFile,
@"C:\Temp"
,
""
)
;
}
Colorized by:
CarlosAg.CodeColorizer
Los tres argumentos del método
ExtractZip
son de tipo string, y son el nombre del fichero ZIP a extraer, la ruta de destino para los ficheros extraídos y una máscara para el tipo de ficheros que debemos extraer. Ojo, no vale una máscara al estilo "*.txt", debe hacerse mediante una expresión regular. Si queremos incluir todos los archivos existentes en el directorio, debemos dejar este último parámetro como
null
o como cadena vacía "".
Y para comprimir:
private static void
ComprimirZipFast()
{
FastZip fZip
= new
FastZip()
;
fZip.CreateZip(
@"C:\Temp\walls.zip"
,
@"C:\Wallpapers"
,
false
,
".jpg$"
)
;
Console.WriteLine(
"Hecho!!"
)
;
}
Colorized by:
CarlosAg.CodeColorizer
En este caso el método
CreateZip
admite cuatro argumentos: el nombre y ruta del fichero ZIP a crear, el directorio donde se encuentran los ficheros que queremos comprimir, un parámetro booleano que indica si la compresión es recursiva (incluimos subdirectorios) o no, y por último un parámetro de tipo string que contiene la máscara para elegir el tipo de ficheros que queremos a comprimir. En este caso es todos los ficheros con extensión JPG. Se aplican las mismas excepciones en uso de máscaras que he comentado para
ExtractZip
.
Categorías:
.NET
|
Artículos
|
Comments [0]
Comments are closed.
Buscar
Estadísticas
Total Posts: 112
This Year: 3
This Month: 0
This Week: 0
Comments: 328
Comentarios Recientes
RE: Microsoft Techdays y...
by Erick Alejan...
RE: Microsoft Techdays y...
by Venkman
RE: Microsoft Techdays y...
by Jesús
RE: Microsoft Techdays y...
by espinete
RE: Microsoft Techdays y...
by Pavleras
Software
Peeker
Acerca de...
Curriculum
Resume
Suscripcion
Suscribirse por correo
Categorias
.NET
Artículos
Blog
Eventos
Gadgets
Hardware
Herramientas
Opinión
Personal
ReSharper
Trucos
Ubuntu
Web
Archivo
January, 2008 (3)
December, 2007 (7)
November, 2007 (13)
October, 2007 (6)
September, 2007 (10)
August, 2007 (1)
July, 2007 (2)
June, 2007 (4)
May, 2007 (3)
March, 2007 (3)
February, 2007 (5)
January, 2007 (5)
December, 2006 (3)
November, 2006 (5)
September, 2006 (2)
August, 2006 (4)
July, 2006 (7)
June, 2006 (3)
May, 2006 (4)
April, 2006 (5)
March, 2006 (5)
February, 2006 (4)
January, 2006 (3)
Los blogs que leo
.Avery Blog
47 hats
Coding Horror
El lado del mal
Haacked
Jon Galloway
NET slave
Rob Conery
secretGeek
The daily WTF
The old new thing
Thinking in .NET
Velocidad de Escape
Contacto
Microblogging
Login
Sign In
Herramientas
Addicted to
The best C# & VB.NET refactoring plugin for Visual Studio 2005
Powered by
newtelligence dasBlog 1.9.7174.0
Tema basado en
Dandelion
, de Tim Sherrill