Python/File
Quando un programma termina, le informazioni contenute nei suoi dati vanno perse. Per conservare delle informazioni tra un'esecuzione e un'altra di un programma o per passare dei dati da un programma ad un altro, si usano i file. Un file è una sequenza di informazioni scritte su un supporto di memoria permanente. La classe file permette di leggere, scrivere e modificare file.
File di testo
modificaPer scrivere stringhe in un file di testo basta aprire il file in scrittura e usare il suo metodo write. Terminato di scrivere nel file basta chiuderlo e questo è disponibile per altre applicazioni.
fo=file('prova.txt', 'w')
fo.write('Primo file di testo:\n\n')
fo.write('terza riga,\n')
fo.write('quarta riga riga,\n')
fo.write('fine del file.')
fo.close()
Leggere un file è altrettanto semplice: aprire il file in lettura, leggere le righe scorrendo il file come una sequenza:
for riga in file('prova.txt'):
print riga,
Se vogliamo salvare in un file dei dati numerici possiamo tradurli in stringhe e salvarli come stringhe. Ad es. creiamo una matrice di numeri interi:
def randmat(dr, dc, massimo):
import random
m=[[random.randrange(massimo) for c in xrange(dc)] for r in xrange(dr)]
return m
matrice=randmat(5, 4, 100)
possiamo salvare la matrice in un file usando le seguenti istruzioni:
def salvamat(matrice, nomefile):
fo=file(nomefile, 'w')
for riga in matrice:
riga=[str(val) for val in riga]
fo.write('\t'.join(riga)+'\n')
fo.close()
salvamat(matrice, 'matrice.txt')
Una funzione che legga la matrice dal file e costruisca una lista di liste è:
def leggimat(nomefile):
fi=file(nomefile)
m=[[int(e) for e in riga.split('\t')] for riga in fi]
fi.close()
return m
E infine qualche riga di codice controlla che lettura e scrittura siano avvenute correttamente.
print matrice
matriceletta=leggimat('matrice.txt')
if matrice==matriceletta:
print 'Salvataggio e lettura effettuati con successo'
else:
print 'La matrice salvata e quella letta sono diverse!'
print 'quella letta è:'
print matriceletta
File binari
modificaUn file binario contiene dati che non sono organizzati in stringhe di caratteri ma è semplicemente una sequenza di byte. Per interpretare un file binario bisogna conoscerne la struttura. Supponiamo di avere un file che contiene 5 stringhe pascal lunghe 20, 20, 1, 2 e 46 caratteri. Ogni stringa pascal ha inoltre un carattere, posto all'inizio, che indica la lunghezza della stringa. Il file dunque è organizzato in blocchi di 94 caratteri:
Per estrarre i dati e tradurlo in un file di testo con i campi separati da virgole, devo leggere tutti i blocchi che compongono il file, interpretarli e scrivere i dati ottenuti in un file di testo. Per aprire in lettura il file binario di nome "CL2PI" si usa il comando:
fi=file("CL2PI", 'rb')
Per leggere un blocco di 94 caratteri sotto forma di sequenza di byte:
r=fi.read(94)
ora ci serve una funzione che legga i 5 campi presenti nel record e ce li restituisca come tupla di sstringhe:
def estrairecord(r):
"""Riceve una riga e la traduce in base alle specifiche."""
return (estrai_stringa_pascal(r, 0),
estrai_stringa_pascal(r, 21),
estrai_stringa_pascal(r, 42),
estrai_stringa_pascal(r, 44),
estrai_stringa_pascal(r, 47),
)
E una funzione che data la posizione del primo carattere di una stringa pascal, quello che ne fornisce la lunghezza, estragga la stringa:
def estrai_stringa_pascal(s, i):
"""Estrae dalla stringa s la sottostringa che inizia in i e che ha
come primo byte la lunghezza, secondo la codifica del Pascal."""
ls=ord(s[i])
return s[i+1:i+ls+1]
Il programma può essere completato con la funzione che legge il file binario e scrive un file di testo:
def estraidati(nomefilein, nomefileout):
"""Traduce il file di ingresso e scrive il file di uscita."""
fi=file(nomefilein, 'rb')
fo=file(nomefileout, 'w')
while True:
r=fi.read(94)
if r:
print estrairecord(r), '\n'
fo.write(','.join(estrairecord(r))+'\n')
else:
break
fo.close()
estraidati('CL2PNI', 'CL2PNI.txt')