Oppure

Loading

Il .NET Framework consente la compressione di dati in modo piuttosto semplice. All'interno del namespace System.IO.Compression, infatti, sono esposte due classi, di nome DeflateStream e GZipStream. Entrambe hanno lo stesso funzionamento e combinano l'algoritmo di compressione LZ77 con la codifica di Huffman. Tuttavia, non sono "indipendenti", poiché devono reggersi sul supporto di un altro stream, che rappresenta la vera connessione con il file da comprimere/decomprimere. Il codice da usare è questo:

Imports System.IO
Imports System.IO.Compression
Module Module1
    Sub Main()
        'I percorsi del file da comprimere e di quello compresso
        Dim File, CompressedFile As String
        'Lo stream che legge i dati da File
        Dim Input As FileStream
        'Lo stream di scrittura associato al file compresso
        Dim Output As FileStream
        'Lo stream compresso che scrive i dati codificati per mezzo
        'dell'output stream
        Dim Zipped As DeflateStream

        Console.WriteLine("Inserire il percorso del file da compriemere:")
        File = Console.ReadLine
        Console.WriteLine("Inserire il percorso in cui salvare i dati compressi:")
        CompressedFile = Console.ReadLine

        'Controlla che il file esista
        If Not IO.File.Exists(File) Then
            Console.WriteLine("File inesistente!")
            Exit Sub
        End If

        'Inizializza lo stream di input
        Input = New FileStream(File, IO.FileMode.Open)
        'Inizializza lo stream di output
        Output = New FileStream(CompressedFile, IO.FileMode.Create)
        'Inizializza lo zipper
        Zipped = New DeflateStream(Output, CompressionMode.Compress)

        'Buffer temporaneo che contiene pacchetti di dati
        Dim Buffer(4095) As Byte

        'Legge i bytes a blocchi di 4KiB
        For I As Int64 = 0 To Input.Length - 1 Step 4096
            If Input.Length - I >= 4096 Then
                Input.Read(Buffer, 0, 4096)
            Else
                Input.Read(Buffer, 0, Input.Length - I)
            End If
            'Li scrive sullo stream compresso
            Zipped.Write(Buffer, 0, Buffer.Length)
        Next

        'Trasferisce  dati compressi sullo stream
        Zipped.Flush()
        'Quindi chiude tutti gli stream
        Zipped.Close()
        Output.Close()
        Input.Close()

        'Alla fine calcola la compressione totale
        'Ottiene la dimensione iniziale del file
        Dim StartSize As Int64 = FileLen(File)
        'E quella finale del file compresso
        Dim EndSize As Int64 = FileLen(CompressedFile)

        Console.WriteLine("Compressione totale: {0:N2}%", _
            100 - (EndSize * 100 / StartSize))
        Console.ReadKey()
    End Sub
End Module 

Potete provare il programma con il file assembly.txt fornito nell'ultima lezione sulla Reflection, la cui compressione sarà circa dell'85%. Bisogna notare che, alla fine del processo, i dati sono sì compressi, ma nessun programma è capace di aprirli se non quello che si è scritto: sebbe l'algoritmo usato sia quello dei file *.zip, non vengono salvate le informazioni necessarie a strutturare lo stream in maniera standard così da poter essere letto normalmente. Nella maggior parte dei casi, questo è un vantaggio: il mio programma Tot Compressor (nella sezione download), usa proprio queste tecniche, ma crea anche una nuova composizione interna per i file in modo da riuscire ad estrapolarne i dati e a stipare più files in uno solo.
Per decomprimere lo stesso file, si agisce in maniera inversa: l'output sarà lo stream del file decompresso, l'input quello compresso e il DeflateStream avrà modalità di compressione Decompress.

A cura di: Il Totem