sabato 21 febbraio 2009

Compact Framework 3.5 comprimere e decomprimere i file

Riporto l'articolo pubblicato per il sito iprogrammatori http://www.iprogrammatori.it/articoli/programmazione/art_compact-framework-35-comprimere-e-decomp_610.aspx



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



Nessun commento: