Input/Output su File in Python
Obiettivi della pillola
In questa guida imparerai a:
- aprire e chiudere i file in sicurezza con
with; - leggere e scrivere file di testo (
.txt,.csv, ecc.); - iterare sulle righe di un file in modo efficiente;
- gestire file binari (immagini, dati grezzi);
- spostarti all’interno di un file con
seek()etell().
Introduzione: Aprire i File
Per lavorare con un file, bisogna prima aprirlo con la funzione open(nome_file, modalità).
Le Modalità di Apertura
Le più importanti sono:
'r'(Read): Lettura (default). Errore se il file non esiste.'w'(Write): Scrittura. Sovrascrive il file se esiste, lo crea se non esiste.'a'(Append): Scrittura in coda. Aggiunge dati alla fine senza cancellare quelli esistenti.'b'(Binary): Da aggiungere alle precedenti per file binari (es.'rb','wb').
Il Context Manager with
È fondamentale chiudere sempre i file per liberare risorse. In Python, il modo migliore è usare il blocco with, che chiude il file automaticamente anche in caso di errori.
# NON FARE COSÌ (rischio se c'è un errore prima di close)
f = open("dati.txt", "r")
content = f.read()
f.close()
# FAI COSÌ (sicuro e pythonico)
with open("dati.txt", "r") as f:
content = f.read()
# Qui il file è già chiuso
File di Testo
Lettura
Ci sono diversi metodi per leggere il contenuto:
read(): Legge tutto il file in un’unica stringa.readline(): Legge una sola riga alla volta (incluso il\nfinale).readlines(): Legge tutte le righe e restituisce una lista di stringhe.- Iterazione diretta: Il metodo più efficiente per file grandi.
# Metodo migliore per scorrere un file riga per riga
with open("elenco.txt", "r") as f:
for riga in f:
# riga contiene anche il carattere "a capo"
print(riga.strip()) # strip() rimuove spazi e \n inizio/fine
Cercare righe specifiche con il ciclo for:
# Il ciclo for è il modo standard per leggere una riga alla volta.
# Non carica tutto il file in memoria!
with open("log.txt", "r") as f:
for riga in f:
if riga.startswith("ERROR:"):
print("Trovato un errore:", riga.strip())
Scrittura
with open("output.txt", "w") as f:
f.write("Prima riga\n") # Bisogna mettere \n esplicitamente
f.write("Seconda riga\n")
# Scrivere una lista di righe
righe = ["Terza\n", "Quarta\n"]
f.writelines(righe)
Esempio: Contare le righe
conteggio = 0
with open("log.txt", "r") as f:
for riga in f:
conteggio += 1
print(f"Il file ha {conteggio} righe.")
File Binari
I file binari (immagini, audio, eseguibili) non sono divisi in righe e non usano codifiche come UTF-8. Si leggono e scrivono come sequenze di byte.
# Copiare un'immagine (byte per byte)
with open("foto.jpg", "rb") as source: # rb = read binary
dati = source.read() # Legge tutti i byte
with open("copia_foto.jpg", "wb") as dest: # wb = write binary
dest.write(dati)
Lettura a blocchi (chunk) con ciclo while — utile per file di grandi dimensioni:
# Per file grandi, si legge "a pezzi" (chunk) fino alla fine
CHUNK_SIZE = 4096 # Leggiamo 4 KB alla volta
with open("video.mp4", "rb") as f:
while True:
dati = f.read(CHUNK_SIZE)
if not dati: # Se la lettura restituisce bytes vuoti, è finito
break
# Elabora i dati (es. salvali, inviali, ecc.)
pass
Nota: Quando leggi in modalità binaria, ottieni oggetti di tipo
bytes(es.b'\x89PNG...'), non stringhe.
Spostarsi nel File: seek() e tell()
Il file ha un “cursore” che indica la posizione corrente (in byte). Quando leggi, il cursore avanza.
tell(): Restituisce la posizione attuale del cursore (intero).seek(offset, whence): Sposta il cursore.offset: Di quanti byte spostarsi.whence: Da dove iniziare (0: inizio file, 1: posizione corrente, 2: fine file).
Nota: Nei file di testo,
seek()è supportato solo parzialmente (solitamente solo all’inizioseek(0)o a posizioni ottenute datell()). Nei file binari è pienamente supportato.
with open("dati.bin", "rb") as f:
print(f.read(10)) # Legge i primi 10 byte
print(f.tell()) # Stampa 10
f.seek(0) # Torna all'inizio
print(f.read(5)) # Rilegge i primi 5 byte
f.seek(0, 2) # Va alla fine del file
dimensione = f.tell() # La posizione alla fine è la dimensione!
print(f"Il file è grande {dimensione} byte")
Esercitazione Pratica
Esercizio 1 — Analisi File Log
Hai un file di testo server.log.
- Conta quante righe contengono la parola “ERROR”.
- Crea un nuovo file
errors_only.txtcopiandoci dentro solo quelle righe.
Esercizio 2 — Messaggio Nascosto
Hai un file binario. Sai che il messaggio segreto inizia al byte 50 e finisce al byte 100. Scrivi uno script che:
- Apre il file in modalità binaria.
- Si sposta al byte 50.
- Legge 50 byte.
- Prova a decodificarli come testo (
dati.decode('utf-8')) e lo stampa.
EC