#42: Abbreviare la dimensione di un file con VB.NET

Come tutti i programmatori sanno, in informatica vengono utilizzate delle abbreviazioni per indicare l’unità di misura per la dimensione di un file, della RAM o di un hard disk: per esempio un file di 1.024 byte equivale a un file di 1 “kB”.

Le abbreviazioni utilizzate attualmente sono le seguenti:

  • kiloByte –> kB –> 1.024 (circa 10^3)
  • MegaByte –> MB –> 1.048.576 (circa 10^6)
  • GigaByte –> GB –> 1.073.741.824 (circa 10^9)
  • TeraByte –> TB –> 1.099.511.627.776 (circa 10^12)
  • PetaByte –> PB –> 1.125.899.906.842.620 (circa 10^15)
  • ExaByte –> EB –> 1.152.921.504.606.850.000 ( circa 10^18 )
  • ZettaByte –> ZB –> 1,180.591.620.717.41E+21 (circa 10^21)
  • YottaByte –> YB –> 1,208.925.819.614.63E+24 (circa 10^24)

Per noi programmatori potrebbe quindi essere utile avere una funzione in grado di abbreviare un numero molto grande, così da avere una rappresentazione molto più compatta. Il seguente codice fa proprio questo:

Module Module1

   Public Function ConvertiByte( _

         ByVal strNumero As String) As String

      Dim risultato As String

      Dim potenza As Integer = 0

      Dim nByte As Decimal = 0

      ‘ verifico se è stato passato un parametro:

      ‘ se si, lo converto nel tipo Decimal

      ‘ se no, esco

      ‘TODO: aggiungere verifica se è un numero valido!

      If strNumero <> “” Then

         Try

            nByte = CType(strNumero, Decimal)

         Catch ex As Exception

            Return “Numero troppo grande: Overflow”

         End Try

      Else

         Return “Errore: nessun numero da valutare”

      End If

      ‘ ciclo di riduzione del numero, estraendo

      ‘ il numero di iterazioni effettuate

      Do While ((nByte / 1000) >= 1)

         nByte = nByte / 1024

         potenza += 1

      Loop

      ‘ conversione in stringa con arrotondamento

      risultato = Decimal.Round(nByte, 2).ToString

      ‘ aggiunta della giusta unità di misura

      Select Case potenza

         Case 0

            risultato &= ” byte”

         Case 1

            risultato &= ” KB”

         Case 2

            risultato &= ” MB”

         Case 3

            risultato &= ” GB”

         Case 4

            risultato &= ” TB”

         Case 5

            risultato &= ” PB”

         Case 6

            risultato &= ” EB”

         Case 7

            risultato &= ” ZB”

         Case 8

            risultato &= ” YB”

         Case Else

            risultato = “Non valutabile”

      End Select

      Return risultato

   End Function

End Module

A questo punto basta creare un form, aggiungere una casella di testo e un pulsante. Il codice per gestire l’evento Click del pulsante è il seguente:

Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, _

         ByVal e As System.EventArgs) Handles Button1.Click

      MessageBox.Show(ConvertiByte(Me.TextBox1.Text))

   End Sub

End Class

Semplice vero? Ma proviamo a migliorare un po’ la nostra funzione. E’ sufficiente sostituire tutto il codice seguente al commento “aggiunta della giusta unità di misura”:

      ‘ aggiunta della giusta unità di misura

      Dim misure() As String = _

         {“byte”, “KB”, “MB”, “GB”, “TB”, “PB”, “EB”, “ZB”, “YB”}

      If potenza > 8 Then

         risultato &= ” Non valutabile”

      Else

         risultato &= ” “ & misure(potenza)

      End If

      Return risultato

Con una semplice modifica, poi, possiamo fare in modo che la nostra funzione rappresenti un’abbreviazione di potenze di 10^3. Per esempio (i punti di separazione delle migliaia sono inseriti solo per chiarezza visiva):

– 1.000 –> 1 x 10^3
– 1.000.000 –> 1 x 10^6
– 55.555.555.555 –> 55,56 x 10^9

Ecco quindi la nostra funzione modificata:

Module Module1

   Public Function ConvertiByte( _

         ByVal strNumero As String) As String

      Dim risultato As String

      Dim potenza As Integer = 0

      Dim nByte As Decimal = 0

      ‘ verifico se è stato passato un parametro:

      ‘ se si, lo converto nel tipo Decimal

      ‘ se no, esco

      ‘TODO: aggiungere verifica se è un numero valido!

      If strNumero <> “” Then

         Try

            nByte = CType(strNumero, Decimal)

         Catch ex As Exception

            Return “Numero troppo grande: Overflow”

         End Try

      Else

         Return “Errore: nessun numero da valutare”

      End If

      ‘ ciclo di riduzione del numero, estraendo

      ‘ il numero di iterazioni effettuate

      Do While ((nByte / 1000) >= 1)

         nByte = nByte / 1000

         potenza += 1

      Loop

      ‘ conversione in stringa con arrotondamento

      risultato = Decimal.Round(nByte, 2).ToString

      ‘ aggiunta della giusta unità di misura

      risultato &= ” x 10^” & (potenza * 3).ToString

      Return risultato

   End Function

End Module

Come potete vedere, le uniche differenze sono date dal diverso divisore (1000 anziché 1024) e nella parte finale, dove viene composta la stringa che viene restituita dalla funzione al codice chiamante.

Una precisazione, prima che qualcuno possa pensare che si tratti di un errore. Il seguente codice:

      Do While ((nByte / 1000) >= 1)

         nByte = nByte / 1024

         potenza += 1

      Loop

potrebbe apparire strano o perfino sbagliato. Perché confronto la divisione per 1000 e poi divido per 1024?

E’ molto semplice: nel caso in cui, per esempio, volessi abbreviare 1000 byte, con il confronto per 1024 otterrei la non esecuzione dell’abbreviazione e quindi il risultato sarebbe “1000 byte” anziché “0,98 KB”. Di solito è abbastanza brutto veder superare il valore di 1000 in questi casi e quindi si preferisce comunque arrivare al massimo a 999 (confrontate per esempio con la visualizzazione dell’Esplora Risorse di Windows).

Una curiosità: notate come sia possibile, in VB.NET, scrivere una cosa del genere:

(potenza * 3).ToString

senza dover memorizzare il calcolo matematico in una variabile.

C’è ancora qualcuno che non è convinto a passare a VB.NET?  🙂

Pubblicato il 2 luglio 2008 su Tips. Aggiungi ai preferiti il collegamento . Lascia un commento.

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: