File

I File sono archivi di dati memorizzati su memoria di massa. La creazione di un file da' la possibilita' di archiviare dati per un uso futuro, sia da parte dello stesso programma che lo ha creato sia da parte di un altro programma.

A seconda della modalita' di organizzazione dei dati su disco, ci sono diversi tipi di file:

File Sequenziali (Sequential)
sono file di testo, che consentono esclusivamente un accesso di tipo sequenziale.
File Random (o Relative)
sono file che memorizzano dati in forma binaria con struttura tabellare; consentono l'accesso diretto, oltre che (ovviamente) quello sequenziale.
File Binari (Binary)
sono file che memorizzano dati in forma binaria, senza una particolare struttura; consentono sia l'accesso diretto che quello sequenziale.

Utilizzo dei file

I file sequenziali sono molto utili per archiviare dati di tipo testo, sia memorizzati in forma libera (file TXT), sia rispettando un formato (file HTML, file XML), sia contenenti parametri di inizializzazione di un programma (file INI), sia contenenti istruzioni di un programma sorgente (file BAS, ...).
I dati letti da un file sequenziale verranno collocati in memoria centrale, in variabili di tipo String.

I file random sono utili per memorizzare dati strutturati sotto forma tabellare, che sono molto usati nei problemi di natura gestionale (ad esempio l'archivio degli studenti di una scuola e l'archivio dei voti degli studenti nelle varie materie).
Le righe di una tabella di dati si chiamano RECORD, mentre le colonne si chiamano CAMPI.
Storicamente, la gestione dei file random e' stata via via potenziata con l'aggiunta di meccanismi e strutture dati ausiliarie (indici) per consentire un rapido accesso ai dati sulla base del loro contenuto (accesso con chiave) e per garantirne la sicurezza (privatezza, tolleranza ai guasti, accesso concorrente da parte di piu' utenti).
Questa evoluzione ha portato a complessi meccanismi di gestione dei dati in forma tabellare, per i quali sono necessari appositi software di gestione: si parla quindi di DATABASE (per la gestione integrata di molteplici tabelle di dati) e di Sistemi di Gestione di Database (esempi: Access, SQL Server, Oracle, DB2).
I dati letti da un file random verranno collocati in memoria centrale, in variabili di tipo Tabella, ovvero Array di Record.

I file binari sono utili per memorizzare dati di qualsiasi tipo, risulta pero' tutta a carico del programma la corretta sequenza di lettura e interpretazione degli stessi: ad esempio e' possibile memorizzare in un file binario il contenuto di tutte le variabili in memoria centrale, con la necessita' di ricordare l'esatto ordine in cui sono state memorizzate, per consentirne un successivo recupero.

Operazioni di apertura e chiusura dei file

La prima operazione che si deve fare su un file e' l'Apertura (Open), che consente di associare un numero di identificazione, detto numero di Canale, ad uno specifico file memorizzato su disco.

Si parla di "numero di Canale" in quanto si interpreta un file come un "flusso di dati" che giungono dal disco fisso all'area di memoria del programma transitando lungo un "canale virtuale".

Inoltre, l'operazione di apertura associa ad un file una zona di memoria centrale, detta BUFFER, gestita dal sistema operativo per accogliere i dati letti da disco, oppure pronti per essere memorizzati su disco.

Si ricorda che l'input/output da disco, per questioni di efficienza, non avviene mai un Byte alla volta bensi' a BLOCCHI di Byte, ad esempio a blocchi di 2048 Byte; cosicche', anche se si e' interessati ad un dato lungo due Byte, si dovranno in realta' leggere dal disco 2048 Byte, dei quali solo i due che interessano verranno collocati in una qualche variabile gestita dal programma.

Se, per caso, in seguito mi interessano altri due Byte, potrei essere fortunato e trovarli gia' nel Buffer, cosicche' non occorre una effettiva lettura da disco, bensi' un semplice trasferimento di dati all'interno della memoria centrale, dal Buffer alla variabile desiderata.

Analogamente per la scrittura su disco: si accumulano nel Buffer i Byte da scrivere su disco, e solo quando il Buffer e' pieno questi dati verranno effettivamente registrati su disco.

Con l'apertura del file si associa allo stesso anche una variabile cursore che tiene traccia della posizione dove si e' arrivati a leggere, o a scrivere: si tratta di una variabile di tipo Long, gestita automaticamente da Visual Basic, che assume come valore la posizione del prossimo dato da leggere/scrivere; con "dato" si intende carattere oppure record oppure byte, rispettivamente per i file sequenziali, random e binari.

Il primo dato di un file ha convenzionalmente la posizione numero 1.

Notare che subito dopo una operazione di lettura/scrittura, il cursore non si trova posizionato sul dato appena letto/scritto, bensi' sul successivo!.

Dopo l'utilizzo del file, lo si deve Chiudere (Close), per liberare tutte le risorse di memoria impegnate dallo stesso, ed anche, per i file su cui si sta scrivendo, per comandare lo scaricamento del Buffer (operazione di Flush), ovvero scriverne il contenuto su disco.

Le altre operazioni che si possono fare su un file sono determinate dalla modalita' di apertura dello stesso.
La sintassi dell'istruzione di apertura e' la seguente:

Open nomeFile For modalitàApertura as #numeroDiCanale [Len = lunghezzaRecord]

dove numeroDiCanale e' un numero intero da 1 a 511, e dove Len = lunghezzaRecord si applica soltanto ai file Random.

I file sequenziali possono essere aperti nei seguenti modi:

  1. esclusivamente per leggerne il contenuto: modalita' Input,
  2. esclusivamente per scriverne il contenuto, sovrascrivendo i dati gia' eventualmente presenti: modalita' Output,
  3. esclusivamente per aggiungere all'attuale contenuto altri dati, che verranno collocati di seguito a quelli gia' presenti: modalita' Append.

I file random vengono aperti unicamente in modalita' Random.
Per essi c'e' la necessita' di specificare la lunghezza del record (espressa in Byte), ovvero la lunghezza di ciascuna riga della tabella.

I file binari vengono aperti unicamente in modalita' Binary.

La sintassi dell'operazione di chiusura e':

Close #numeroDiCanale

Esempi:


' apro in input un file sequenziale associato al canale 1
Open "amici.txt" For Input as #1

' apro in output un file sequenziale associato al canale 2
Open "c:\documenti\nuovo.txt" For Output as #2

' apro in modalita' append un file sequenziale
nomeFile = "amici.txt"
n = FreeFile()  ' funzione predefinita che restituisce il primo 
                ' numero di canale che risulta libero
Open nomeFile For Append as #n

' apro un file random contenente un archivio di studenti
' notare che le stringhe devono essere a lunghezza fissa!
Type Studente
  Nome as String*20
  Classe as String*4
  VotoItaliano as Integer
  VotoMatematica as Integer
End Type
Dim rec as Studente
Open "studenti.dat" For Random as #1 Len = Len(rec)

' apro un file binario
n = 1
Open "foto.gif" For Binary as #n

Modalita' di accesso

La modalita' di accesso sequenziale consiste nel leggere, o scrivere, i dati uno di seguito all'altro, senza avere la possibilita' di saltare direttamente ad una determinata posizione per leggere, o scrivere, qualcosa.

Questa modalita' e' l'unica possibile quando i dati archiviati hanno lunghezza diversa.
Si pensi ad esempio ad un testo composto di righe piu' o meno lunghe: poiche' le righe hanno un diverso numero di caratteri, l'unico modo per poter individuare la posizione da dove inizia l'n-esima riga di testo e' leggere tutte le precedenti n-1 righe.

La modalita' di accesso diretto, invece, consiste nella possibilita' di leggere/scrivere un dato, posizionandosi direttamente nella posizione desiderata.
Essa presuppone che tutti i dati memorizzati (in questo caso si parla di Record = unita' di registrazione) abbiano la stessa lunghezza L cosicche' risulta possibile individuare immediatamente la posizione di inizio dell'n-esimo dato:

P = (n - 1) * L + 1

Infatti, i primi n-1 record occupano complessivamente (n - 1) * L Byte, e quindi il Byte successivo e' quello da cui inizia l'n-esimo record.

Si vuole precisare che, per quanto riguarda i file binari, l'accesso diretto lo si ha a livello di Byte, ovvero si puo' saltare direttamente all'n-esimo Byte.

La modalita' di accesso con chiave , invece, consiste nella possibilita' di leggere/scrivere un record di dati, posizionandosi direttamente su di esso senza conoscerne la posizione bensi' conoscendone soltanto una parte del contenuto.
Tutto questo presuppone oltre che tutti i dati memorizzati abbiano lunghezza fissa anche la presenza di strutture dati ausiliarie per l'accesso ai dati, quali "indici" e/o strutture "hash", di cui, in questa sede, non si discutera' oltre.

Operazioni su un file sequenziale

Un file sequenziale memorizza caratteri.

Se viene aperto in Input, un file sequenziale puo' soltanto essere letto.

Di solito e' opportuno verificare che il file esista, prima di tentare di aprirlo, con la funzione Dir$(nomeFile), la quale restituisce una stringa vuota se nomeFile non esiste, altrimenti restituira' una stringa contenente il nome del file medesimo. Esempio:


If Dir$("amici.txt") <>"" Then  'il file esiste
   Open "amici.txt" For Input as #1
   ...
   Close #1
Else  'il file non esiste
   ...
End If

Prima di qualsiasi operazione di lettura e' necessario controllare che il cursore non abbia gia' raggiunto e superato la fine del file.

Questo controllo viene fatto con la funzione booleana End Of File, EOF(numeroDiCanale).

Il programma puo' facilmente determinare se si e' o meno raggiunti la fine del file poiche' conosce la dimensione del file (essa e' fornita dal sistema operativo).

Se il cursore e' posizionato sull'ultimo carattere del file allora la condizione EOF risulta Falsa, se invece esso e' posizionato oltre l'ultimo carattere, allora essa risulta Vera.

Subito dopo l'apertura, il cursore si trova posizionato sul primo Byte; qualora il file aperto sia vuoto, la condizione EOF risulta immediatamente Vera.

Mano a mano che si leggono i caratteri memorizzati nel file, il cursore viene automaticamente fatto avanzare, in modo da puntare sempre al carattere successivo all'ultimo che e' stato letto.

Le istruzioni di lettura sono Input e Line Input e c'e' anche la funzione Input().

Se i dati memorizzati nel file sono separati da virgola, come ad esempio le seguenti due righe di dati:


"Salve", 234
"Ciao", 24
allora conviene leggerli con l'istruzione Input.

In effetti la memorizzazione avviene interponendo la coppia di caratteri CR e LF tra i dati di una riga e quelli della successiva:

"Salve", 234CRLF"Ciao", 24

Il "formato CSV" (Comma Separated Values = Valori Separati da Virgola) rappresenta un utilissimo modo per scambiare valori di forma tabellare tra programmi diversi: ad esempio da Excel ad un programma scritto in Visual Basic.

Una porzione di codice per la lettura del file puo' essere il seguente:


Dim a as String
Dim n as Integer
Open "prova.csv" For Input As #1 ' Apre il file e pone il cursore sul primo car.
Do While Not EOF(1)   ' Ripete fino alla fine del file
   Input #1, s, n     ' Legge i dati nelle variabili e fa avanzare il cursore
   MsgBox "Ho letto" & s & " e " & CStr(n)   ' Messaggio di verifica
Loop
Close #1   ' Chiude il file

Notare che, per una corretta lettura, e' necessario conoscere la "struttura" di ciascuna riga di dati del file.

Se i dati sono memorizzati nel file come testo libero come ad esempio (le righe sono sempre separate dalla coppia di caratteri CR e LF):


Questa e' una lettera
da leggere
con molta
attenzione perche' e' molto interessante.
Conviene leggere il file una riga alla volta, con l'istruzione Line Input, come illustrato dal seguente esempio:

Dim riga as String
Open "lettera.txt" For Input As #1   ' Apre il file
Do While Not EOF(1)   ' Ripete fino alla fine del file
   Line Input #1, riga   ' Assegna la riga a una variabile
   MsgBox riga   ' Messaggio di verifica
Loop
Close #1   ' Chiude il file

E' anche possibile leggere tutto il file con un'unica istruzione, facendo uso della funzione Input(numeroDiByte, numeroDiCanale) e della funzione LOF(numeroDiCanale) la quale restituisce la lunghezza del file (Length Of File) espressa in Byte, ovvero il numero di caratteri che costituiscono il file. Esempio:


Dim s as String
Open "pagina.htm" For Input As #1
s = Input (LOF(1), 1)  ' leggo interamente il file HTML
Close #1

Se un file sequenziale viene aperto in modalita' Output, oppure Append, e' possibile soltanto effettuare l'operazione di scrittura.

Nel primo caso si crea il file, mentre nel secondo si utilizza un file preesistente.

Di solito e' opportuno verificare che il file non esista, prima di tentare di aprirlo in modalita' Output, per evitare di sovrascrivere il contenuto di un file gia' esistente:


If Dir$("amici.txt") = "" Then   'il file non esiste
   Open "amici.txt" For Output as #1
   ...
   Close #1
Else  'il file esiste
   ...
End If
Viceversa per l'apertura in modalita' Append.

Per scrivere in un file sequenziale si possono usare le istruzioni Print e Write, la prima consente di scrivere un testo libero costituito da piu' righe separate dalla coppia di caratteri CR e LF, mentre la seconda consente di scrivere i dati contenuti in piu' variabili separandoli da virgola.

Entrambe aggiungono automaticamente ai dati da scrivere la coppia di caratteri CR e LF per ottenere il "ritorno a capo".

Esempio con Print:


Open "lettera.txt" For Output As #1   ' Apre il file per l'output
Print #1, "Questa � una prova"   ' Scrive il testo nel file
Print #1,   ' Scrive una riga vuota nel file
Print #1, "Salve gente"
Print #1, "il valore e' " & CStr(500)
Close #1
Si ottiene:

Questa � una prova

Salve gente
il valore e' 500

Anzi, piu' precisamente:

Questa � una provaCRLFCRLFSalve gente CRLFil valore e' 500CRLF

Esempio con Write:


Dim s as String
Dim n as Integer
' CSV sta per Comma Separated Values (valori separati da virgola)
Open "prova.csv" For Output as #1
s = "Salve"
n = 234
Write #1, s, n
Write #1, "Ciao", 24
Close #1   ' Chiude il file.
Si ottiene

"Salve", 234
"Ciao", 24

Anzi, piu' precisamente:

"Salve", 234CRLF"Ciao", 24CRLF

Non e' possibile modificare direttamente un file sequenziale, e' necessario aprirlo in Input, leggerne il contenuto e trascriverlo, con le modifiche desiderate, in un altro file aperto in Output.

Operazioni su un file random

Nei file random si memorizzano tipicamente dei Record, di cui si deve dichiarare la struttura con l'istruzione Type.

Ad esempio per dichiarare il tipo Articolo, che descrive ciascun articolo presente in un magazzino di merci:


Private Type Articolo
   Codice as String*4
   Descrizione as String*20
   PrezzoUnitario as Currency
   Quantit�InGiacenza as Double
End Type
I record devono essere a lunghezza fissa, per consentire l'accesso diretto agli stessi.

La dimensione del record deve essere specificata nell'istruzione Open.

L'istruzione Open apre un file random esistente oppure crea un nuovo file random.

Per scrivere si usa l'istruzione Put e per leggere l'istruzione Get.

La sintassi e' rispettivamente:

Put #numeroDiCanale, posizione, variabileDaScrivere

Get #numeroDiCanale, posizione, variabileDaLeggere

dove il parametro posizione e' un numero di tipo Long che specifica la posizione a partire dalla quale leggere/scrivere la variabile indicata. Se omesso si intende la posizione corrente del cursore, che subito dopo l'apertura del file si trova sul primo record, ovvero alla posizione numero 1.

Per conoscere la posizione corrente del cursore si usa la funzione Seek(numeroDiCanale), la quale restituisce un numero Long che rappresenta la posizione del record corrente, ovvero il prossimo che sara' letto/scritto.

Il cursore avanza automaticamente a seguito delle operazioni di lettura/scrittura Get e Put; tuttavia per sfruttare la possibilita' di accesso diretto si deve impostare la posizione del cursore sul record desiderato con l'istruzione Seek: Seek #numeroDiCanale, posizione

Il cursore puo' essere posizionato direttamente su qualsiasi record del file, oppure subito dopo l'ultimo record presente in modo da consentire l'aggiunta di nuovi record allo stesso.

Per scorrere in modo sequenziale un file random, si puo' usare la condizione EOF, vista per i file sequenziali.

Per poter aggiungere un nuovo record si deve innanzitutto determinare il numero di record presenti con l'espressione:

n = LOF(numeroDiCanale) / Len(record)

dove LOF(numeroDiCanale) fornisce la lunghezza in Byte del file; e poi posizionare il cursore alla posizione successiva con l'istruzione:

Seek #numeroDiCanale, n + 1

Esempio: caricamento in un file random dei dati di una tabella memorizzata in un array.


Private Type Articolo
   Codice as String*4
   Descrizione as String*20
   PrezzoUnitario as Currency
   Quantit�InGiacenza as Double
End Type

Private Sub CaricaFile(ByRef arr() as Articolo)
Dim rec as Articolo
Dim i as Long

Open "articoli.dat" For Random as #1 Len = Len(rec)
For i = 0 To UBound(arr)
   Put #1,,arr(i)
Next i
Close #1
End Sub

Esempio: aumento del 10% dei prezzi di tutti gli articoli.


Private Sub AumentaPrezzi()
Dim rec as Articolo
Dim posizione as Long

Open "articoli.dat" For Random as #1 Len = Len(rec)
Do While Not EOF(1)
   Get #1,,rec ' legge un record
   rec.PrezzoUnitario = rec.PrezzoUnitario * 1.10
   posizione = Seek(1) - 1  ' determina la posizione del record appena letto
   Seek #1, posizione  ' posiziona il cursore sul record appena letto
   Put #1,,rec   ' riscrive il record con i dati modificati
Loop
Close #1
End Sub
Operazioni su un file binario

Un file binario memorizza byte.

L'istruzione di apertura di un file binario lo crea se esso non esiste!

Si scrive con l'istruzione Put e si legge con l'istruzione Get. Esempio di scrittura:


Dim n as Integer
Dim b as Byte
Dim f as String*10
Dim s as String
n = 5800
b = 1
f = "1234"   ' si ottiene la stringa  "1234      " 
s = "abcdefghijklmnopqrst"  ' stringa di 20 caratteri
                            ' (corrisponde a 20 Byte su disco)
Put #1,,n  ' scrive 2 Byte
Put #1,,b  ' scrive 1 Byte
Put #1,,f  ' scrive 10 Byte
Put #1,,s  ' scrive 20 Byte
Esempio di lettura, il numero di Byte che vengono letti dipende dalla variabile usata nell'istruzione Get:

Dim n as Integer
Dim b as Byte
Dim f as String*10
Dim s as String
s = Space$(20)  'si prepara ad accogliere 20 byte
Get #1,,n  ' legge 2 Byte
Get #1,,b  ' legge 1 Byte
Get #1,,f  ' legge 10 Byte
Get #1,,s  ' legge 20 Byte
Si nota che per leggere correttamente si deve ricordare l'esatta sequenza delle variabili che sono state scritte.

Esempio: la memorizzazione di un array di Integer:


Private Sub MemorizzaArray(ByRef arr() as Integer)
Dim n as Long
n = UBound(arr)
Open "array.bin" For Binary as #1
Put #1,,n   ' memorizzo la dimensione dell'array
Put #1,,arr() 'memorizzo il contenuto dell'array
Close #1
End Sub
Esempio: la lettura di un array di Integer:

Private Function CaricaArray() as Integer()
Dim n as Long
n = UBound(arr)
Open "array.bin" For Binary as #1
Get #1,,n   ' legge la dimensione dell'array
ReDim CaricaArray(n) as Integer  ' dimensiona l'array
Get #1,,arr() 'memorizzo il contenuto dell'array
Close #1
End Sub
Per leggere un file binario un Byte alla volta, si deve controllare di andare oltre la lunghezza del file con le funzioni:

Seek(numeroDiCanale) che restituisce un valore Long che specifica la posizione del Byte corrente del cursore di lettura/scrittura, e
LOF(numeroDiCanale) che restituisce un valore Long che specifica la lunghezza del file espressa in Byte.

Esempio:


Dim b as Byte
Open "prova.bin" For Binary as #1
Do While Seek(1) <= LOF(1)
   Get #1,,b   ' legge il byte corrente
   ...
Loop
Close #1

oppure, lo stesso risultato puo' essere ottenuto nel seguente modo:


Dim b as Byte
Dim i as Long
Open "prova.bin" For Binary as #1
For i = 1 to LOF(1)
   Get #1,,b   ' legge il byte corrente
   ...
Next i
Close #1
Applicazione: un "file splitter", ovvero un programma che prende in input un file di grandi dimensioni e lo suddivide (split) in piu' file di dimensioni piu' piccole, ad esempio per poterlo inviare a rate tramite posta elettronica. Ovviamente occorre anche effettuare l'operazione inversa di riassemblaggio, mediante un "file joiner".


Private Sub FileSplitter()
Dim maxSize as Long
Dim j as Long
Dim n as Long
Dim nomeFileInput as String
Dim nomeFileOutput as String
Dim nomeFile as String
Dim estensioneFile as String
Dim b() as Byte
nomeFileInput = InputBox("Nome del file da suddividere:") ' es.: ALFA.DOC
nomeFile = Left$(nomeFileInput, Len(nomeFileInput)-4)
estensioneFile = Right$(nomeFileInput, 3)
maxSize = InputBox("Dimensione massima da ottenere (in KByte):")
j = 0  ' contatore
Open nomeFileInput For Binary as #1
Do While Seek(1) <= LOF(1)
  j = j + 1
  ' creo il nome del j-esimo file di output - esempio ALFA001.DOC
  nomeFileOutput = nomeFile & Format(j, "000") & "." & estensioneFile
  Open nomeFileOutput For Binary as #2
  ' supp. di avere la funzione Min(x,y) che da' il minimo di due valori
  ' n sara' il numero di Byte da leggere
  n = Min(1024*maxSize, LOF(1) - Seek(1) + 1)
  ReDim b(1 to n)
  Get #1,,b
  Put #2,,b
  Close #2
Loop
Close #1
MsgBox "Lavoro finito!"
End Sub

Private Sub FileJoiner()
Dim maxSize as Long
Dim j as Long
Dim n as Long
Dim nomeFileInput as String
Dim nomeFileOutput as String
Dim nomeFile as String
Dim estensioneFile as String
Dim b() as Byte
Dim finito as Boolean

finito = False
nomeFileInput = InputBox("Nome dei file da riassemblare:") ' es.: ALFA*.DOC
nomeFile = Left$(nomeFileInput, Len(nomeFileInput)-5)
estensioneFile = Right$(nomeFileInput, 3)
nomeFileOutput = nomeFile & "." & estensioneFile
Open nomeFileOutput For Binary as #1
j = 0  ' contatore
Do While not finito
  j = j + 1
  ' creo il nome del j-esimo file di input - esempio ALFA001.DOC
  nomeFileInput = nomeFile & Format(j, "000") & "." & estensioneFile
  If Dir$(nomeFileInput)="" Then  ' il file non c'e'
     finito = True
  Else
     Open nomeFileInput For Binary as #2
     n = LOF(1) 
     ReDim b(1 to n)
     Get #2,,b
     Put #1,,b
     Close #2
   End If
Loop
Close #1
MsgBox "Lavoro finito!"
End Sub
Intercettazione degli errori

Quando si lavora con i file ci sono molte situazioni che possono causare un errore run-time che interrompe l'esecuzione del programma, quali ad esempio il tentativo di aprire in input un file non esistente, il tentativo di leggere dati oltre la fine del file, il tentativo di usare un numero di canale gia' in uso da parte di un altro file, ecc...

Per evitare la brusca interruzione del programma e dare eventualmente all'utente la possibilita' di ritentare l'operazione, ad esempio correggendo il nome del file da aprire in input, e' opportuno introdurre un meccanismo di intercettazione degli errori run-time.

Si utilizza l'istruzione

On Error GoTo etichetta

per saltare all'etichetta indicata ed eseguire le istruzioni che la seguono.

L'oggetto predefinito Err fornisce le utili proprieta' Err.Number e Err.Description che consentono di risalire, rispettivamente, al codice numerico e alla descrizione dell'errore generato.

Il seguente esempio illustra un possibile modo di gestire l'apertura di un file da floppy disk:


Private Sub cmdOK_Click()
Dim isOpen As Boolean
Dim s As String
On Error GoTo Gestione_Errore 'in caso di errore lo rimanda al gestore
isOpen = False  ' ora il file non e' aperto
Open "a:\pippo.txt" For Input As #1 
isOpen = True ' se arrivo qui allora il file e' aperto
Do While Not EOF(1)
   Input #1, s
   MsgBox s
Loop
Close #1
Exit Sub ' Esco dalla Sub saltando le istruzioni che seguono!

Gestione_Errore:
' si puo' fornire il messaggio di errore:
MsgBox CStr(Err.Number) & " - " & Err.Description
' si puo' eventualmente chiedere se si vuole ritentare:
If Err.Number = 71  ' errore "disco non pronto"
   Risposta = MsgBox("vuoi riprovare?", vbYesNo)
   If Risposta = vbYes Then Resume  ' ritorna ad eseguire l'istruzione
                                    ' che ha causato l'errore
End If
If isOpen Then Close #1  ' chiudo il file se e' rimasto aperto
End Sub

Il seguente esempio arricchisce il precedente, fornendo anche la possibilita' di ritentare qualora il file da aprire non esista:


Private Sub cmdOK_Click()
Dim isOpen As Boolean
Dim s As String
Dim nomeFile as String
On Error GoTo Gestione_Errore 'in caso di errore lo rimanda al gestore
isOpen = False  ' ora il file non e' aperto
nomeFile = InputBox ("Nome del file da aprire:")
Open nomeFile For Input As #1 
isOpen = True ' se arrivo qui allora il file e' aperto
Do While Not EOF(1)
   Input #1, s
   MsgBox s
Loop
Close #1
Exit Sub ' Esco dalla Sub saltando le istruzioni che seguono!

Gestione_Errore:
' si puo' fornire il messaggio di errore:
MsgBox CStr(Err.Number) & " - " & Err.Description
' si puo' eventualmente chiedere se si vuole ritentare:
If Err.Number = 53 Then ' errore "impossibile trovare il file"
   nomeFile = InputBox("Nome del file da aprire")
   If nomeFile <> ""  Then 
      Resume  ' ritenta
   Else
      MsgBox "... allora sara' per un'altra volta"
   End If
End If
If Err.Number = 71 Then  ' errore "disco non pronto"
   Risposta = MsgBox("Vuoi riprovare?", vbYesNo)
   If Risposta = vbYes Then 
      Resume  ' ritenta
   Else
      MsgBox "... allora sara' per un'altra volta"
   End If
End If
If isOpen Then Close #1  ' chiudo il file se e' rimasto aperto
End Sub

La seguente tabellina elenca i principali errori run-time che riguardano l'accesso a file su disco.

CODICE ERRORE DESCRIZIONE
52"Nome o Numero di file non valido"
oppure cerco di leggere da un file che non e' stato aperto
53"Impossibile trovare il file"
riguarda ad es. le istruzioni Open, Kill, Name
54"Modalit� file non valida"
ad es.: Put o Get usati per file che non sono Random ne' Binary
Print# usato per file aperti in Input
Input# usato per file aperti in Output o Append
55"File gia' aperto"
si verifica quando tento di aprire un file che risulta gia' aperto
57"Errore di I/O sulla periferica"
errore di I/O da disco o su stampante
58"File gia' esistente"
59"Lunghezza del record non valida"
61"Disco pieno"
62"Input oltre la fine del file"
63"Numero di record non valido"
67"Troppi file aperti"
67"Periferica non disponibile"
causato ad es. da una connessione di rete interrotta
70"Autorizzazione negata"
71"Disco non pronto"
75"Errore di accesso al percorso/file"
76"Impossibile trovare il percorso"

Ci si rende subito conto che una gestione, seppur minimale, degli errori complica alquanto la scrittura dei programmi. Operazioni di servizio sui file

Visual Basic fornisce alcune istruzioni utili per la manutenzione dei file. Ad esempio e' possibile cancellare un file con l'istruzione:

Kill "amici.txt"

che accetta anche i caratteri jolly:

Kill "*.txt"

E' possibile copiare un file con l'istruzione:

FileCopy "c:\documenti\sorgente.txt", "c:\temp\destinazione.txt" FileCopy "lavoro.dat", "lavoro.bak"

E' possibile rinominare un file con l'istruzione:

Name "vecchio.txt" as "nuovo.txt"

Affiche' le suddette istruzioni possano funzionare, i file su cui agiscono non devono essere aperti.