Grazie allo script che ora vi illustro è possibile numerare le righe di un file di testo con estensione .txt oppure di un file asp3 con estensione .asp o un file asp.net avente estensione aspx. Da dove nasce l'idea di questo script? Nasce dalla mia necessità di numerare le righe di codice quando Vi illustro gli articoli e le guide su freeASP.it per indicare esattamente la parte che sto spiegando.
Ora vediamo sia il codice che l'output finale del nostro file:
01: <%@ page language="vb" EnableViewState="true" %>
02: <%@ Import Namespace="System.IO" %>
03: <script language="vb" runat="server">
04:
05: Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
06: 'Inserire qui il codice utente necessario per inizializzare la pagina
07: End Sub
08:
09: Private Sub btLeggi_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
10:
11: try
12:
13: lbEsito.text=""
14:
15: Dim objFlusso As StreamReader
16: Dim strLine As String
17: Dim strFile As String
18: strFile = tbFile.PostedFile.FileName
19: Dim intRighe As Integer
20: intRighe = 0
21: Dim intLunghezza As Integer
22:
23: objFlusso = New StreamReader(strFile)
24:
25:
26: strLine = objFlusso.ReadLine
27:
28: Do While Not strLine Is Nothing
29: intRighe = intRighe + 1
30: strLine = objFlusso.ReadLine
31: Loop
32:
33: intLunghezza = Len(Str(intRighe))
34:
35: objFlusso.Close()
36:
37: objFlusso = New StreamReader(strFile)
38:
39: strLine = objFlusso.ReadLine
40:
41: intRighe = 0
42:
43: Do While Not strLine Is Nothing
44: intRighe = intRighe + 1
45: lbEsito.Text = lbEsito.Text & testoFormattato(intRighe, intLunghezza)
& ": " & Server.HtmlEncode(strLine) & "<br>"
46: strLine = objFlusso.ReadLine
47: Loop
48:
49: objFlusso.Close()
50: catch
51: lbEsito.text="Errore Improvviso. Riprovare."
52: end try
53:
54: End Sub
55:
56: Function testoFormattato(ByVal numero As Integer, ByVal quante As Integer)
As String
57: Dim ctInd As Integer
58: testoFormattato = Str(numero)
59: testoFormattato = Trim(testoFormattato)
60: For ctInd = Len(Str(numero)) + 1 To Str(quante)
61: testoFormattato = "0" & testoFormattato
62: Next
63: End Function
64:
65: </script>
66:
67: <HTML>
68: <HEAD>
69: <title>leggiFile</title>
70: </HEAD>
71: <body bottomMargin="10" leftMargin="10" topMargin="10" rightMargin="10">
72: <form id="Form1" method="post" runat="server" EncType="multipart/form-data">
73: <asp:Label id="lbTitolo" runat="server" Font-Names="Tahoma">File da leggere</asp:Label><br>
74: <Input ID="tbFile" Type="file" runat="Server" ><br>
75: <asp:Button id="btLeggi" runat="server" Text="Leggi il File" OnClick="btLeggi_Click"></asp:Button><br>
76: <asp:Label id="lbEsito" runat="server" Width="100%"></asp:Label><br>
77: </form>
78: </body>
79: </HTML>
Non trovate comodo leggere in maniera distinta tutte le righe del codice sorgente? Ora vediamo come funziona (indicando naturalmente le righe). Dalla riga 67 alla 79, abbiamo la costruzione di un web form:
72: <form id="Form1" method="post" runat="server" EncType="multipart/form-data">
...il nostro form...
77: </form>
contenente una label col titolo della pagina:
73: <asp:Label id="lbTitolo" runat="server" Font-Names="Tahoma">File da leggere</asp:Label><br>
la casella di upload del file (dove indicheremo quale file deve leggere)
74: <Input ID="tbFile" Type="file" runat="Server"
><br>
il pulsante che aziona il meccanismo del form
75: <asp:Button id="btLeggi" runat="server" Text="Leggi il File" OnClick="btLeggi_Click"></asp:Button><br>
ed infine la label dove andremo a mostrare il risultato prodotto.
76: <asp:Label id="lbEsito" runat="server" Width="100%"></asp:Label><br>
Ora vediamo come funziona la sub-routine btLeggi_Click (le righe sono dalla
09 alla 54) che ha il compito di leggere il file e di mostrare il risultato finale a video tramite l'aiuto esterno della funzione testoFormattato (le righe sono dalla 56 alla 63).
Nella sub-routine btLeggi_Click dopo aver aperto il flusso di lettura del file indicato:
15: Dim objFlusso As StreamReader
23: objFlusso = New StreamReader(strFile)
viene effettuata una prima lettura sino a quando il dato letto è nullo. In tal caso, significa che non vi sono dati da leggere all'interno del file. Cosa significa? Significa che o siamo arrivati alla fine del file, oppure il file è vuoto e quindi non vi è nulla da leggere.
26: strLine = objFlusso.ReadLine
27:
28: Do While Not strLine Is Nothing
29: intRighe = intRighe + 1
30: strLine = objFlusso.ReadLine
31: Loop
In questa prima fase, vengono conteggiate le righe presenti all'interno del
file che si desidera formattare a video (riga 29). Perché si fa questa lettura
senza mostrare nessun dato e si contano solo le righe? La risposta è molto semplice: non mi piace mostrare un listato con i numeri che hanno prima una cifra, poi due, poi tre, ... e poi N cifre per indicar la riga.
Nella riga successiva, viene calcolato il numero di cifre necessarie per comporre il numero totale di righe appena calcolato:
33: intLunghezza = Len(Str(intRighe))
La parte successiva, è quella che realmente prepara l'output a video
leggendo il contenuto effettivo di ogni singola riga del file:
39: strLine = objFlusso.ReadLine
40:
41: intRighe = 0
42:
43: Do While Not strLine Is Nothing
44: intRighe = intRighe + 1
45: lbEsito.Text = lbEsito.Text & testoFormattato(intRighe, intLunghezza)
& ": " & Server.HtmlEncode(strLine) & "<br>"
46: strLine = objFlusso.ReadLine
47: Loop
Come potete notare nella riga 45, viene aggiornata la label che contiene il
risultato finale. Per mostrare il numero della riga si utilizza la funzione creata testoFormattato che richiede in ingresso il numero della riga in cui si trova il dato che stiamo leggendo e la quantità di cifre necessarie per scrivere il numero massimo delle righe presenti nel file. Come ritorno la funzione rende un valore in formato stringa che è il numero di riga opportunamente formattato.
56: Function testoFormattato(ByVal numero As Integer, ByVal quante As
Integer) As String
57: Dim ctInd As Integer
58: testoFormattato = Str(numero)
59: testoFormattato = Trim(testoFormattato)
60: For ctInd = Len(Str(numero)) + 1 To Str(quante)
61: testoFormattato = "0" & testoFormattato
62: Next
63: End Function
Come si effettua la formattazione del numero della riga? Semplice. Basta anteporre una quantità variabile di zeri in modo da alzare la lunghezza sino ad arrivare a quella massima. Il valore elaborato viene inserito in testoFormattato in modo da tornare come stringa ed esser utilizzato alla riga 45 del listato.
Una volta terminato il tutto, il file viene chiuso.
49: objFlusso.Close()
L'intera elaborazione dei dati viene effettuata all'interno di un blocco try/catch in modo da poter gestire errori imprevisti.
Prima di concludere l'articolo, vorrei dare un consiglio. Modificate la riga uno:
01: <%@ page language="vb" EnableViewState="true"
%>
nel seguente modo:
01: <%@ page language="vb" EnableViewState="false" %>
Ora vi illustro il perché di questa modifica:
Esempio numero 1 | Stato ViewState | |
Dimensioni | true | false |
File txt | 192 Kb |
192 Kb |
ViewState | 292 Kb |
102 Byte |
Pagina .aspx elaborata | 508 Kb |
216 Kb |
% occupata dal ViewState | 57,48 % |
0.05 % |
Numero di righe file.txt | 2697 | 2697 |
Esempio numero 2
|
Stato ViewState | |
Dimensioni
|
true | false |
File txt | 52 Kb |
52 Kb |
ViewState | 112 Kb |
75 Byte |
Pagina .aspx elaborata | 188 Kb |
80 Kb |
% occupata dal ViewState | 59.57 % |
0.09 % |
Numero di righe file.txt | 2998 | 2998 |
Come potete osservare, indipendentemente dalla natura del file, dalla sua dimensione e dal numero di righe in esso contenute il ViewState assume una porzione di pagina non indifferente. Di conseguenza consiglio vivamente di disattivarlo per risparmiare tempo ed aumentare la velocità di esecuzione di pagina. Non voglio dire che il ViewState sia inutile, anzi è un ottimo elemento delle pagine .aspx ma non sempre è necessario ed un buon programmatore deve sapere quando è corretto usarlo e quando no. In questo caso, la risposta sull'uso e scontata: "ViewState, no grazie."