Indice del libro


Questa parte tratterà la lettura/scrittura e gestione dei file.

In Perl questo tipo di operazione è stata semplificata al massimo, pertanto le operazioni da fare sono ridotte a tre:

  1. apertura: prevede diversi modi: in lettura, in scrittura, in aggiunta o misti
  2. lettura/scrittura: si risolve con una istruzione.
  3. chiusura: è unica per tutti i tipi di apertura (ricordarsi di chiudere i file nonostante al termine del programma il Perl chiude tutto ciò che è rimasto aperto).

APERTURA in lettura (file di testo ASCII)

modifica

Per aprire un file si usa la funzione open.

Questa funzione richiede come parametri una "espressione", chiamata FILEHANDLE, per poter gestire il file, e il nome del file

open ( MIOFILE , "pippo.txt" );

NOTA: a essere espliciti occorrerebbe scrivere open ( MIOFILE , "<pippo.txt" ); ma la open di default è in lettura.

La funzione open ritorna un "false" in caso di problemi e imposta la variabile speciale $! che contiene il motivo indicato dal sistema operativo (es: file inesistente , non posso aprire il file, etc...)

$esito = open ( MIOFILE , "pippo.txt" );
if ( ! $esito )
{
    die ( "Non è stato possibile aprire il file pippo.txt : $!" ); 
}

oppure:

if ( ! open ( MIOFILE , "pippo.txt" ) )
{
   die ( "Non è stato possibile aprire il file pippo.txt : $!" ); 
}

oppure ancora:

unless ( open ( MIOFILE , "pippo.txt" ) ) 
{
   die ( "Non è stato possibile aprire il file pippo.txt : $!" ); 
}

Sfruttando l'operatore || è possibile aprire un file o far uscire dal programma informando del motivo con una sola riga di codice:

open ( MIOFILE , "pippo.txt" ) || die ( "Non è stato possibile aprire il file pippo.txt : $!" );

che sicuramente ha una forma pulita.

LETTURA di un file (di testo)

modifica

Una volta aperto senza problemi, per leggere il file si utilizza il FILEHANDLE. Questo è sensibile al contesto :

  • se chi riceve il dato è uno scalare ritorna una riga
  • se chi riceve il dato è un array ritorna tutto il contenuto del file, dove ogni riga del file è un elemento dell'array )

Vediamo:

while ( $linea = <MIOFILE> )
{
   print $linea;
}

oppure

@tuttoIlFile = <MIOFILE>; 
print @tuttoIlFile;
ATTENZIONE
il FILEHANDLE viene usato tra < e > quando si legge!

CHIUSURA di un file

modifica

Per chiudere un file si usa la funzione close() che richiede il FILEHANDLE da chiudere. Infatti un programma può aprire più file alla volta.

close ( MIOFILE );

APERTURA in scrittura di un file (di testo)

modifica

Per poter scrivere in un file (NOTA: solo scrivere!) occorre aggiungere al nome file il simbolo '>' Vediamo un esempio:

open ( MIOFILE , ">pippo.txt" );

ATTENZIONE: con questa operazione si è di fatto creato un nuovo file, vuoto, cancellando il vecchio.

Come nel caso della lettura, se non ritorna un false allora l'operazione è riuscita e pertanto è possibile applicare nello stesso modo i controlli:

$esito = open ( MIOFILE , ">pippo.txt" );
if ( ! $esito )
{
    die ( "Non è stato possibile aprire il file pippo.txt : $!" ); 
}

oppure :

if ( ! open ( MIOFILE , ">pippo.txt" ) )
{
   die ( "Non è stato possibile aprire il file pippo.txt : $!" ); 
}

oppure :

unless ( open ( MIOFILE , ">pippo.txt" ) ) 
{
   die ( "Non è stato possibile aprire il file pippo.txt : $!" ); 
}

oppure la più semplice :

open ( MIOFILE , ">pippo.txt" ) || die ( "Non è stato possibile aprire il file pippo.txt : $!" );

SCRITTURA di un file (di testo)

modifica

Per scrivere in un file è sufficiente utilizzare la print indicando il FILEHANDLE. Infatti se non specificato (di default) la print usa il video (STDOUT).

print MIOFILE "Questo l'ho scritto io\n";

APERTURA in aggiunta di un file (di testo)

modifica

Questa modalità è comoda per aggiungere linee a un file senza rimuoverne il precedente contenuto. Per farlo si possono usare i simboli '>>' prima del nome file:

open ( MIOFILE , ">>pippo.txt" );

Come nei casi precedenti è possibile fare i controlli che l'operazione si sia svolta correttamente:

$esito = open ( MIOFILE , ">>pippo.txt" );
if ( ! $esito )
{
    die ( "Non è stato possibile aprire il file pippo.txt : $!" ); 
}

etc ...

SCRITTURA in aggiunta di un file (di testo)

modifica

Si usa lo stesso costrutto visto prima :

 print MIOFILE "Questo l'ho scritto io\n";

APERTURA,LETTURA/SCRITTURA "mista" di un file (di testo)

modifica

È possibile aprire un file per leggerci e scriverci.

Queste modalità su di un file (di testo) sono tutte equivalenti. Come vi sarete accorti con le modalità precedenti, occorrerà mettere dei simboli ad indicare :

  • '+<' lettura e scrittura # non crea un nuovo file (cursore all'inizio)
  • '+>' scrittura e lettura # crea un nuovo file (cursore all'inizio)
  • '+>>' aggiunta e lettura # non crea un nuovo file (cursore in fondo)
open ( MIOFILE , "+>pippo.txt" ) || die ( "Non è stato possibile aprire il file pippo.txt : $!" );

Ovviamente la scrittura "sovrascrive" il contenuto (non inserisce il nuovo testo) e quindi occorre usarla con cautela.

Ogni volta che leggiamo da file usiamo "inconsapevolmente" un cursore.

Per esempio quando leggiamo una riga con il codice :

 $riga = <MIOFILE>;

posiziona il cursore al primo carattere successivo alla fine della riga e quindi alla successiva richiesta fornisce la successiva riga.

Per muoversi "agevolmente" nel file si usa la funzione seek che ha il preciso scopo di spostarsi nel file.

La funzione seek ha la seguente sintassi:

seek ( FILEHANDLE , num_byte , dove );
  • FILEHANDLE assume lo stesso significato delle altre funzioni;
  • num_byte è il numero di byte da saltare. È un numero che può essere positivo o negativo a seconda di "dove"

NOTA: si parla di byte e non di caratteri: il legame dipende dal sistema operativo!

  • dove: se 0 indica inizio dall'inizio del file, se 1 indica dalla posizione corrente del file, se 2 indica dalla fine del file.

quindi:

seek( MIOFILE , 0 , 0 ); # si posiziona all'inizio del file
seek( MIOFILE , 0 , 1 ); # si posiziona dov'è ora ! ( e rimane nel file )
seek( MIOFILE , 0 , 2 ); # si posiziona in fondo al file

Per sapere la posizione assoluta alla quale è arrivato il cursore (posizione dall'inizio del file) è possibile usare l'istruzione tell:

$numByte_Ora = tell( MIOFILE ); # Posizione attuale del cursore

Se tell incontra problemi ritorna un numero negativo.

Vediamo ora questo esempio che rendono meglio l'idea:

open ( MIOFILE , "+<pippo.txt" ) || die ( "Non \350 stato possibile aprire il file pippo.txt : $!" );

print "posizione appena aperto :".tell( MIOFILE )." \n";
seek ( MIOFILE , 0 , 2); # mi metto in fondo
print "posizione al fondo :".tell( MIOFILE )." \n";
 
seek ( MIOFILE , 0 , 0); # mi metto all'inizio
while ( $linea = <MIOFILE> )
{ 
  print "--$linea--".tell(MIOFILE)."\n"; # scrivo il file ed indico la posizione nel file
} 

print "posizione fine :".tell( MIOFILE )."\n"; # scrivo la posizione raggiunta nel file (la fine)

 
print MIOFILE "riga aggiunta\n"; # scrivo una nuova riga !
print "Ultima posizione valida :".tell( MIOFILE )." \n";

close ( MIOFILE );

Questo script scrive in fondo al file la riga "riga aggiunta\n" ma mostra il valore di tell man mano che si "scorre" il file (con la seek o con la semplice lettura ). Quindi lanciandolo più volte si otterrà questo risultato:

posizione appena aperto :0 
posizione al fondo :70     
--riga aggiunta            
--14                       
--riga aggiunta            
--28                       
--riga aggiunta            
--42                       
--riga aggiunta            
--56                       
--riga aggiunta            
--70                       
posizione fine :70         
Ultima posizione valida :84
NOTA
I numeri cambiano da macchina a macchina ...