IntroduzioneIn applicazioni enterprise molte volta capita che sia necessario dover lavorare con formati di compressione. Per far ciò abbiamo bisogno degli strumenti adatti, soprattutto che non costino uno sproposito, questo strumento è
SharpZipLib, strumento
Open Source (quindi gratuito) e con molte potenzialità, infatti possiamo lavorare oltre che con il formato
Zip anche con i formati
GZip, Tar e BZip2.
In questo articolo daremo un'introduzione alle possibili applicazioni del componente, le più comuni, estrazione contenuto file zip e creazione di un archivio.
Download e InstallazioneIl componente lo potete scaricare al seguente indirizzo:
http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx ">Download #ZipLib
troverete le seguenti opzioni: Codice e esempi, assembly già compilato con relativi script di installazione e il file di help.
In questo caso consiglio di scaricare la versione con l'assembly, mentre gli amanti dell'Open possono scaricarsi il codice e compilare la propria versione.
Una volta scaricato e estratto il contenuto del file zip, non dobbiamo far altro che eseguire il programma dos
installGAC.bat da prompt dei comandi di
Visual Studio .NET, che installerà il componente nella
GAC del nostro PC, per controllare che l'installazione sia andata a buon fine, basta andare nella lista degli assembly registrati nell?applicativo di configurazione del
.NET Framework, che si trova negli stumenti di amministrazione, e cercare
ICSharpCode.SharpZipLib.
Contenuto file ZipCominciamo la nostra carrellata delle feature del componente con il visualizzare il contenuto di un file zip. Apriamo il nostro
Visual Studio .NET (o il nostro editor preferito) e creiamo una nuova
Windows application. Tra le
References del nostro progetto aggiungiamo l'assembly
ICSharpCode.SharpZipLib.
Dalla finestra di dialogo che si apre clicchiamo sul tasto browse e cerchiamo la
DLL sul nostro PC(
ICSharpCode.SharpZipLib.dll), dopo di che clicchiamo sul tasto OK.
Ora siamo pronti ad utilizzare nel nostro progetto il componente. A questo punto creiamo una nuova form o una nuova classe e importiamo il namespace:
using ICSharpCode.SharpZipLib.Zip;
Ora dobbiamo elencare il contenuto del nostro file. E' da premettere che il componente rappresenta un file Zip come un oggetto
ZipFile, e l'elenco degli elementi al suo interno si chiamano
Entry. Quindi non dobbiamo far altro che creare un oggetto ZipFile, dopo di che ciclare sulla collection delle entry, quindi:
Creo l'oggetto
ZipFile passando come unico argomento il path completo del file zip:
ZipFile zFile = new ZipFile(strNomefile);
Dopo di che creo un ciclo sulla collection delle entry del mio file.
foreach(ZipEntry objZip in zFile)
{
. . .
}
A questo punto all'interno del ciclo ricaverò il nome della mia entry e lo stampo a video:
MessageBox.Show(objZip.Name);
Oltre al nome ho tutta un'altra serie di proprietà, tra cui la dimensione del file e la data di creazione della entry.
ATTENZIONE: Le directory sono considerate come entry, quindi oltre ai file vi verranno restituite anche le directory, per evitare questo si dovrà fare un
if che controllerà che nel nome della entry esista un nome di un file:
string fileName = Path.GetFileName(objZip.Name);
if(fileName != string.Empty)
{
. . .
}
Estrarre il contenuto di un file ZipOra che siamo riusciti a vedere il contenuto di un file Zip, estraiamo il suo contenuto all'interno di una directory da noi scelta. Per poter compattare un file zip, il componente ci offre l'oggetto
ZipInputStream che come argomento vuole lo strema del file Zip.
//creo un nuovo oggetto Input stream per l'estrazione
ZipInputStream s = new ZipInputStream(File.OpenRead(strNomefile));
A questo punto devo ciclare sul file e per ogni entry aprire uno stream di byte e creare il file. Per poter far ciò ci viene fornito un metodo
.GetNextEntry() che ci ritorna la entry successiva a quella attuale, quindi dovremo fare un controllo che nel momento in cui non esisterà più la entry successiva usciremo dal ciclo
//variabile di controllo
bool myControl = true;
//ciclo fino a quando non trovo una entry
Do
{
//nel caso non esista una entry successiva esco dal ciclo
theEntry = s.GetNextEntry();
if(theEntry == null)
{
myControl = false;
break;
}
. . .
}
while(myControl);
Ora all'interno del mio ciclo devo fare una serie di controlli prima di estrarre il file, primo fra tutti se la entry è un file e non una directory, dopo di che controllare che la directory del file esista, nel caso contrario crearla.
//Imposto la directory di estrazione che è la directory da me scelta
string strDestinationPath = "c:\\";
//Ricavo il nome della direcory della entry
string directoryName = Path.GetDirectoryName(theEntry.Name);
//Ricavo il nome del file della entry
string fileName = Path.GetFileName(theEntry.Name);
//controllo che sia un file e non una directory
if(fileName != String.Empty && strDestinationPath != "")
{
//se non esiste la directory la creo
if(!Directory.Exists(strDestinationPath + "\\" + directoryName))
{
Directory.CreateDirectory(strDestinationPath + "\\" + directoryName);
}
. . .
}
Ora che abbiamo fatto tutti I controlli del caso, all'interno del nostro
if apriamo uno
StreamWriter e cicliamo sul buffer della entry, e scriviamo byte per byte nel nostro Stream:
//apro un oggetto stream writer per creare il nuovo file
FileStream streamWriter = File.Create(strDestinationPath + "\\" + directoryName + "\\" + fileName);
int size = 2048;
byte[] data = new byte[2048];
//ciclo sul buffer della entry fino a quando non è vuoto
while(true)
{
size = s.Read(data, 0, data.Length);
if(size > 0)
{
streamWriter.Write(data, 0, size);
}
else
{
break;
}
}
//chiudo lo stream writer
streamWriter.Close();
Al termine del ciclo troveremo all'interno della cartella di partenza da noi selezionata il file Zip scompattato.
Creare file zipA questo punto non ci rimane altro che analizzare come creare un file zip, che rispetto all'estrazione è molto più semplice. Come per l'estrazione c'era un oggetto incaricato dell'operazione, anche per la creazione di un file archivio dobbiamo creare un oggetto
ZipOutputStream:
//Creo l'oggetto ZipOutputStream per la creazione del file zip
//e creo anche il file
ZipOutputStream s = new ZipOutputStream(File.Create(strZipFileName));
Dopo di che devo aprire un
FileStream per leggere i byte del file:
//apro un file stream sul file
FileStream fs = File.OpenRead(strNomeFile);
//creo l'array di byte
byte[] buffer = new byte[fs.Length];
//Leggo il buffer
fs.Read(buffer, 0, buffer.Length);
Ora dobbiamo creare una nuova entry nel nostro file zip, e scrivere il buffer dei dati:
//creo una nuova entry
ZipEntry myEntry = new ZipEntry(strNomeFile);
//Aggiungo la entry al file zip
s.PutNextEntry(myEntry);
//Scrivo il buffer
s.Write(buffer, 0, buffer.Length);
ConclusioniIn questo articolo abbiamo visto come possiamo gestire I file
Zip con .NET, con l'aiuto di un piccolo componente
Open Source. Come abbiamo visto il suo utilizzo non è così immediato, ma essendo open source ci permette di risparmiare qualche euro, in cambio di poche righe di codice. Inoltre il componente è alla versione
0.61, quindi ce ne sarà ancora di strada fino alla release 1.0, non potrà che migliorare.