Compact Framework 3.5 comprimere e decomprimere i file

L'articolo illustra una tecnica di come comprimere e decomprimere i file in ambiente mobile tramite il Compact Framework 3.5.

il
Sviluppatore Microsoft .Net, Collaboratore di IProgrammatori

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