Con l’uscita della nuova versione del Compact Framework 3.5 sono state introdotte nuove classi. Il namespace System.io.Compression, contiene al suo interno diverse classi per la gestione dei file, in particolare per comprimere e decomprime file e cartelle.
In questo articolo vedremo come comprimere e decomprimere un file.
Creazione del progetto
Dopo aver creato un nuovo progetto smart device ,in Visual Studio 2008, aggiungiamo nella form, quattro caselle di testo, con altrettanti label per i vari titoli quattro pulsanti, il tutto come mostrato in figura 1.
Figura 1
Come si può vedere dalla figura 1, i controlli situati nella parte superiore, avranno il compito di comprimere i file, selezionato nel proprio device, mentre quelli posti al di sotto del pulsante, con la proprietà text impostata con il testo “Crea File zip – comprimi” permetto di selezionare il file zippato in precedenza e decomprimerlo.
Stesura di codice
Una volta creata la nostra finestra di esempio, passiamo in visualizzazione codice,
Per gestire i file, occorre utilizzare lo spazio dei nomi system.io, mentre per la gestione delle classi per comprimere e decomprime i file, occorre utilizzare il namespace system.io.compression.
Di seguito si riporta tali dichiarazioni.
VB.Net
Imports System.IO
Imports System.IO.Compression
C#
using System.IO;
using System.IO.Compression;
una volta aggiunti iI namespace si creano due funzioni per comprimere e decomprimere I file
La funzione per comprimere i file, accetta due argomenti, il primo il percorso ed il nome del file da comprimere, mentre il secondo argomento, il percorso e nome del file zippato, quello che verrà generato.
Tramite le classi FileStream e GZipStream, possiamo gestire i file e la modalità di compressione.
Di seguito si riporta i frammenti di codice delle suddette operazioni.
VB.Net
Public Sub Comprimi(ByVal origine As String, ByVal Destinazione As String)
'Verifico che il file esista
If File.Exists(origine) = False Then
MessageBox.Show("File da comprimere inestisistente")
Exit Sub
End If
' creazione dello stream del file da zippatre
Dim buffer As Byte() = Nothing
Dim StreamOrigine As FileStream = Nothing
Dim StreamDestinazione As FileStream = Nothing
Dim FileZip As GZipStream = Nothing
Try
' Leggo lo stream dati del file
StreamOrigine = New FileStream(origine, FileMode.Open, FileAccess.Read, FileShare.Read)
' recupero i byte del file
buffer = New Byte(StreamOrigine.Length) {}
Dim dimensione As Integer = StreamOrigine.Read(buffer, 0, buffer.Length)
' Apro un stream per il file di scrittura (zip)
StreamDestinazione = New FileStream(Destinazione, FileMode.OpenOrCreate, FileAccess.Write)
'imposto il file compresso
FileZip = New GZipStream(StreamDestinazione, CompressionMode.Compress, True)
'Scrivo nel file compresso il buffer
FileZip.Write(buffer, 0, buffer.Length)
MessageBox.Show("Operazione terminata")
Catch ex As ApplicationException
MessageBox.Show("Errore: " & ex.Message, "Funzione: Comprimi", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1)
Finally
'libero la memoria
If Not (StreamOrigine Is Nothing) Then
StreamOrigine.Close()
End If
If Not (FileZip Is Nothing) Then
FileZip.Close()
End If
If Not (StreamDestinazione Is Nothing) Then
StreamDestinazione.Close()
End If
End Try
End Sub
C#
void Comprimi(string origine, string Destinazione)
{
//Verifico che il file esista
if (File.Exists(origine) == false)
{
MessageBox.Show("File da comprimere inestisistente");
return;
}
// creazione dello stream del file da zippatre
Byte[] buffer = null;
FileStream StreamOrigine = null;
FileStream StreamDestinazione = null;
GZipStream FileZip = null;
try
{ // Leggo lo stream dati del file
StreamOrigine = new FileStream(origine, FileMode.Open, FileAccess.Read, FileShare.Read);
// recupero i byte del file
buffer = new Byte[StreamOrigine.Length];
Int32 dimensione = StreamOrigine.Read(buffer, 0, buffer.Length);
// Apro un stream per il file di scrittura (zip)
StreamDestinazione = new FileStream(Destinazione, FileMode.OpenOrCreate, FileAccess.Write);
//imposto il file compresso
FileZip = new GZipStream(StreamDestinazione, CompressionMode.Compress, true);
//Scrivo nel file compresso il buffer
FileZip.Write(buffer, 0, buffer.Length);
MessageBox.Show("Operazione terminata");
}
catch (Exception ex)
{
MessageBox.Show("Errore: " + ex.Message, "Funzione: Comprimi", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
}
finally
{
//libero la memoria
if (StreamOrigine != null)
StreamOrigine.Close();
if (FileZip != null)
FileZip.Close();
if (StreamDestinazione != null)
StreamDestinazione.Close();
}
}
La funzione decomprimi, accetta due argomenti di tipo stringa, il primo il percorso ed il nome del file zippato, mentre il secondo argomento, il percorso ed il nome del file che sarà decompresso
L’utilizzo della classe filestream, è utile per gestire il flusso dei dati, mentre la classe GZipStream, lavora sulla compressione dei file.
Qui di seguito si riporta il frammento di codice della funzione decomprimi
VB.Net
Public Sub Decomprimi(ByVal Origine As String, ByVal Destinazione As String)
'Verifico che i file esista
If File.Exists(Origine) = False Then
MessageBox.Show("File da decomprimere inestisistente")
Exit Sub
End If
'Creo lo strem dei file
Dim StreamOrigine As FileStream = Nothing
Dim StreamDestinazione As FileStream = Nothing
Dim FileDecomprimere As GZipStream = Nothing
Dim Dati As Byte() = Nothing
Try
'leggo il file da decomprimere
StreamOrigine = New FileStream(Origine, FileMode.Open)
'Creo l'oggetto che mi decomprime il file
FileDecomprimere = New GZipStream(StreamOrigine, CompressionMode.Decompress, True)
'Imposto le dimensioni del byte
Dati = New Byte(4) {}
Dim posizione As Integer = CType(StreamOrigine.Length, Integer) - 4
StreamOrigine.Position = posizione
StreamOrigine.Read(Dati, 0, 4)
StreamOrigine.Position = 0
Dim dimensione As Integer = BitConverter.ToInt32(Dati, 0)
Dim buffer(dimensione + 100) As Byte
Dim offset As Integer = 0
Dim total As Integer = 0
'leggo il file compresso
While True
Dim bytesRead As Integer = FileDecomprimere.Read(buffer, offset, 100)
If bytesRead = 0 Then
Exit While
End If
offset += bytesRead
total += bytesRead
End While
'scrivo il nuovo file
StreamDestinazione = New FileStream(Destinazione, FileMode.Create)
StreamDestinazione.Write(buffer, 0, total)
' libero il buffer
StreamDestinazione.Flush()
MessageBox.Show("File decompresso")
Catch ex As Exception
MessageBox.Show("Errore " & ex.Message, "Funzione Decomprimi", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1)
Finally
'Libero i vari oggetti utilizzati
If Not (StreamOrigine Is Nothing) Then
StreamOrigine.Close()
End If
If Not (FileDecomprimere Is Nothing) Then
FileDecomprimere.Close()
End If
If Not (StreamDestinazione Is Nothing) Then
StreamDestinazione.Close()
End If
End Try
End Sub
C#
void Decomprimi(string Origine, string Destinazione)
{
//Verifico che i file esista
if (File.Exists(Origine) == false)
{
MessageBox.Show("File da decomprimere inestisistente");
return;
}
//Creo lo strem dei file
FileStream StreamOrigine = null;
FileStream StreamDestinazione = null;
GZipStream FileDecomprimere = null;
Byte[] Dati = null;
try
{
//leggo il file da decomprimere
StreamOrigine = new FileStream(Origine, FileMode.Open);
//Creo l'oggetto che mi decomprime il file
FileDecomprimere = new GZipStream(StreamOrigine, CompressionMode.Decompress, true);
//Imposto le dimensioni del byte
Dati = new Byte[4] ;
Int32 posizione = Convert.ToInt32(StreamOrigine.Length) - 4;
StreamOrigine.Position = posizione;
StreamOrigine.Read(Dati, 0, 4);
StreamOrigine.Position = 0;
Int32 dimensione = BitConverter.ToInt32(Dati, 0);
byte[] buffer = new byte[dimensione + 100];
Int32 offset = 0;
Int32 total = 0;
//leggo il file compresso
while (true)
{
Int32 bytesRead = FileDecomprimere.Read(buffer, offset, 100);
if (bytesRead == 0)
break;
offset += bytesRead;
total += bytesRead;
}
//scrivo il nuovo file
StreamDestinazione = new FileStream(Destinazione, FileMode.Create);
StreamDestinazione.Write(buffer, 0, total);
// libero il buffer
StreamDestinazione.Flush();
MessageBox.Show("File decompresso");
}
catch (Exception ex)
{
MessageBox.Show("Errore " + ex.Message, "Funzione Decomprimi", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
}
finally
{
//Libero i vari oggetti utilizzati
if (StreamOrigine != null)
StreamOrigine.Close();
if (FileDecomprimere != null)
FileDecomprimere.Close();
if (StreamDestinazione != null)
StreamDestinazione.Close();
}
}
Ora dobbiamo gestire i pulsanti che si trovano vicino alle caselle di testo, questi pulsanti, avranno il compito di aprire una finestra di dialogo per la selezione dei file e cartelle.
Per il pulsante della casella di testo, con il titolo impostato a file da comprimere, dobbiamo aggiungere il seguente frammento di codice, nell’evento click di tale pulsante.
Qui di seguito è riportato il codice.
VB.Net
Private Sub btnCercaFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCercaFile.Click
Dim dlgApri As New OpenFileDialog()
dlgApri.Filter = "*.*|*.*"
If dlgApri.ShowDialog = Windows.Forms.DialogResult.OK Then
txtFileDaComprimere.Text = dlgApri.FileName
End If
End Sub
C#
private void btnCercaFile_Click(object sender, EventArgs e)
{
OpenFileDialog dlgApri = new OpenFileDialog();
dlgApri.Filter = "*.*|*.*";
if (dlgApri.ShowDialog() == DialogResult.OK)
txtFileDaComprimere.Text = dlgApri.FileName;
}
Mentre per il pulsante posto accanto alla casella di testo, con il titolo “Nome del file zip” nell’evento click inserire il seguente frammento di codice.
VB.Net
Private Sub btnCercaFileZipDaComprimere_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCercaFileZipDaComprimere.Click
Dim dlgSalva As New SaveFileDialog()
dlgSalva.Filter = "File Zip|*.zip"
If dlgSalva.ShowDialog() = Windows.Forms.DialogResult.OK Then
Dim fleinfo As New FileInfo(dlgSalva.FileName)
txtNomeFileZip.Text = dlgSalva.FileName
txtNomeFileZip.Text = txtNomeFileZip.Text.Replace(fleinfo.Extension, ".zip")
End If
C#
private void btnCercaFileZipDaComprimere_Click(object sender, EventArgs e)
{
SaveFileDialog dlgSalva = new SaveFileDialog();
dlgSalva.Filter = "File Zip|*.zip";
if (dlgSalva.ShowDialog() == DialogResult.OK)
{
FileInfo fleinfo = new FileInfo(dlgSalva.FileName);
txtNomeFileZip.Text = dlgSalva.FileName;
txtNomeFileZip.Text = txtNomeFileZip.Text.Replace(fleinfo.Extension, ".zip");
}
}
A questo punto la parte per comprimere i file è terminata, c’è rimasta la parte per decomprimere il file compresso, o meglio, impostare gli eventi click dei pulsanti per la ricerca dei file .zip e per la la sezione del percorso e nome del file, che sarà compresso.
Per l’evento click del pulsante posto sulla destra della casella di testo, con la scritta “file compresso – da decomprimere”, dobbiamo aprire una finestra di dialogo per la selezione del file compresso, utilizzando la classe openfiledialog.
Qui di seguito si riporta tale frammento di codice.
VB.Net
Private Sub BtnFileDaDecomprimere_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnFileDaDecomprimere.Click
Dim dlgApri As New OpenFileDialog()
dlgApri.Filter = "*.zip*|*.zip*"
If dlgApri.ShowDialog = Windows.Forms.DialogResult.OK Then txtFileCompresso.Text = dlgApri.FileName
End Sub
C#
private void BtnFileDaDecomprimere_Click(object sender, EventArgs e)
{
OpenFileDialog dlgApri = new OpenFileDialog();
dlgApri.Filter = "*.zip*|*.zip*";
if (dlgApri.ShowDialog() == DialogResult.OK)
txtFileCompresso.Text = dlgApri.FileName;
}
Mentre per l’evento click del pulsante che si trova al lato della casella di testo con il titolo impostato nel seguente modo “Percorso e cartelle dove decomprimere” utilizzeremo la classe savefiledialog, il quale apre una finestra di dialogo per il salvataggio del file.
Qui di seguito si riporta il frammento di codice di tali operazioni.
VB.Net
Private Sub btnPercorsoEcartellaDecompresso_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPercorsoEcartellaDecompresso.Click
Dim dlgApri As New SaveFileDialog()
dlgApri.Filter = "*.*|*.*"
If dlgApri.ShowDialog = Windows.Forms.DialogResult.OK Then txtFileDecompresso.Text = dlgApri.FileName
End Sub
C#
private void btnPercorsoEcartellaDecompresso_Click(object sender, EventArgs e)
{
SaveFileDialog dlgApri = new SaveFileDialog();
dlgApri.Filter = "*.*|*.*";
if (dlgApri.ShowDialog() == DialogResult.OK)
txtFileDecompresso.Text = dlgApri.FileName;
}
Ora per l’evento del pulsante, con la scritta “Crea file zip – Comprimi” inseriamo il codice per richiamare la funzione per comprimere i file.
Qui di seguito si riporta il frammento di codice delle suddette operazioni.
VB.Net
Private Sub BtnComprimi_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnComprimi.Click
If txtNomeFileZip.Text.Trim() = "" OrElse txtFileDaComprimere.Text.Trim() = "" Then Return
Comprimi(txtFileDaComprimere.Text, txtNomeFileZip.Text)
End Sub
C#
private void BtnComprimi_Click(object sender, EventArgs e)
{
if (txtNomeFileZip.Text.Trim() == "" || txtFileDaComprimere.Text.Trim() == "")
return;
Comprimi(txtFileDaComprimere.Text, txtNomeFileZip.Text);
}
Infine, occorre richiamare dal pulsante decomprimi file zip, la funzione per decomprimere I file.
Qui di seguito si riporta tale codice:
VB.Net
Private Sub BtnDecomprimi_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If txtFileDecompresso.Text.Trim() = "" OrElse txtFileCompresso.Text.Trim() = "" Then Return
Decomprimi(txtFileCompresso.Text, txtFileDecompresso.Text)
End Sub
C#
private void BtnDecomprimi_Click(object sender, EventArgs e)
{
if (txtFileDecompresso.Text.Trim() == "" || txtFileCompresso.Text.Trim() == "")
return;
Decomprimi(txtFileCompresso.Text, txtFileDecompresso.Text);
}
Conclusioni
In questo articolo, è stata illustrata una tecnica di come comprimere e decomprimere i file, naturalmente l’articolo ha voluto fornire le basi al lettore per queste nuove classi per la gestione dei file. Il lettore, potrà ampliare nonché sviluppare un applicativo con funzionalità avanzate, per questo nuovo modo di lavorare sui file in ambiente mobile.
Tramite la parola download potete scaricare il file di esempio utilizzato in questo articolo.
Download