Python/File

Wikibooks, manuali e libri di testo liberi.
Jump to navigation Jump to search
Indice del libro


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[modifica]

Per 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 'Slvataggio e lettura effettuati con successo'
else:
    print 'La matrice salvata e quella letta sono diverse!'
    print 'quella letta è:'
    print matriceletta

File binari[modifica]

Un 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')