Introduzione
Quando si parla di gestione dei file in Python, spesso si pensa subito a file di testo, CSV o JSON. In realtà, una parte molto importante dello sviluppo riguarda i file binari: immagini, PDF, archivi compressi, file audio, database locali, dati esportati da un’applicazione o contenuti scaricati da rete.
Un file binario non è leggibile come testo normale: i suoi byte devono essere trattati con attenzione, usando modalità di apertura corrette, lettura a blocchi e controlli accurati. Questo è fondamentale per evitare corruzione dei dati, errori di memoria e problemi di compatibilità tra sistemi.
In questo tutorial vedremo come leggere, scrivere, copiare e verificare file binari in Python con un approccio pulito e sicuro. L’obiettivo è darti una base solida per lavorare con immagini, documenti e altri formati non testuali in modo professionale.
Codice completo
from pathlib import Path
import hashlib
import shutil
def calcola_hash_sha256(percorso_file: Path, chunk_size: int = 8192) -> str:
"""Restituisce l´hash SHA-256 di un file binario."""
digest = hashlib.sha256()
with percorso_file.open("rb") as file:
while True:
blocco = file.read(chunk_size)
if not blocco:
break
digest.update(blocco)
return digest.hexdigest()
def copia_file_binario(sorgente: Path, destinazione: Path) -> None:
"""Copia un file binario in modo sicuro."""
destinazione.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(sorgente, destinazione)
def leggi_primi_byte(percorso_file: Path, n: int = 16) -> bytes:
"""Legge i primi n byte del file."""
with percorso_file.open("rb") as file:
return file.read(n)
def scrivi_file_binario(percorso_file: Path, dati: bytes) -> None:
"""Scrive byte grezzi su disco."""
percorso_file.parent.mkdir(parents=True, exist_ok=True)
with percorso_file.open("wb") as file:
file.write(dati)
def aggiungi_byte(percorso_file: Path, dati: bytes) -> None:
"""Aggiunge byte alla fine di un file binario esistente."""
with percorso_file.open("ab") as file:
file.write(dati)
def verifica_integrita(sorgente: Path, copia: Path) -> bool:
"""Confronta due file tramite hash SHA-256."""
return calcola_hash_sha256(sorgente) == calcola_hash_sha256(copia)
def main() -> None:
base_dir = Path("dati_binari")
sorgente = base_dir / "immagine_originale.bin"
copia = base_dir / "backup" / "immagine_copia.bin"
# Simuliamo un file binario di esempio
dati_iniziali = bytes([137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82])
scrivi_file_binario(sorgente, dati_iniziali)
# Lettura dei primi byte
intestazione = leggi_primi_byte(sorgente, 8)
print("Intestazione file:", intestazione)
# Aggiunta di byte in coda
aggiungi_byte(sorgente, b"x00x01x02x03")
# Copia sicura del file
copia_file_binario(sorgente, copia)
# Verifica integrità
uguali = verifica_integrita(sorgente, copia)
print("File identici:", uguali)
# Hash del file
print("SHA-256 sorgente:", calcola_hash_sha256(sorgente))
print("SHA-256 copia:", calcola_hash_sha256(copia))
if __name__ == "__main__":
main() Spiegazione
Il codice mostra una serie di operazioni tipiche sui file binari, tutte basate su un principio essenziale: aprire il file con la modalità giusta.
1. Apertura in modalità binaria
Quando usi "rb", "wb" o "ab", Python lavora con byte grezzi invece che con stringhe. Questo è importante perché un file binario non deve essere interpretato come testo.
- rb: lettura binaria
- wb: scrittura binaria, sovrascrive il file
- ab: aggiunta in coda al file
Se provassi a leggere un’immagine o un PDF in modalità testuale, potresti ottenere errori o dati alterati.
2. Lettura a blocchi
La funzione calcola_hash_sha256 legge il file a blocchi da 8192 byte. Questa tecnica è fondamentale per file grandi, perché evita di caricare tutto il contenuto in memoria.
Il pattern è molto comune nei programmi professionali:
- leggi un blocco
- aggiorni il digest o elabori i dati
- passi al blocco successivo
In questo modo il codice resta efficiente anche con file di grandi dimensioni, come video o archivi compressi.
3. Scrittura sicura
La funzione scrivi_file_binario crea la cartella di destinazione se non esiste e poi scrive i byte nel file. Questo è utile in script di automazione, export o backup, dove la struttura delle directory può non essere presente in anticipo.
Usare mkdir(parents=True, exist_ok=True) è una buona pratica perché rende il codice più robusto e meno fragile.
4. Aggiunta in coda
La modalità "ab" serve quando vuoi aggiungere dati alla fine di un file già esistente. È utile, per esempio, in alcuni formati di log binari, buffer di dati o file di raccolta incrementale.
5. Copia del file
Per copiare un file binario, il modulo shutil è una scelta ottima. La funzione copy2 copia il contenuto e conserva anche i metadati principali, come timestamp e permessi, quando possibile.
6. Verifica dell’integrità
Confrontare due file tramite hash SHA-256 è una tecnica semplice e molto affidabile. Se due file hanno lo stesso hash, con probabilità estremamente alta sono identici.
Questo è utile per:
- verificare backup
- controllare download
- confrontare esportazioni
- individuare corruzione dei dati
Nel nostro esempio, dopo aver copiato il file, confrontiamo hash sorgente e copia per assicurarci che la copia sia perfetta.
Best practice
- Usa sempre il contesto
withper aprire i file: garantisce la chiusura automatica anche in caso di errore. - Apri i file binari con modalità binaria (
rb,wb,ab): evita conversioni indesiderate tra testo e byte. - Leggi a blocchi i file grandi: è più efficiente e riduce il consumo di memoria.
- Preferisci
pathliba stringhe di percorso: rende il codice più leggibile e portabile tra sistemi operativi. - Verifica l’integrità con hash quando copi o scarichi file importanti.
- Crea le directory prima di scrivere: evita errori dovuti a percorsi inesistenti.
- Non interpretare byte come testo se non sei certo del formato: codifiche errate possono rompere i dati.
Riepilogo
Gestire file binari in Python significa lavorare con byte, non con stringhe. Questo cambia il modo in cui apri, leggi e scrivi i file, ma il linguaggio offre strumenti semplici e potenti per farlo bene.
In questo tutorial hai visto come:
- aprire file in modalità binaria
- leggere solo una parte del contenuto
- scrivere e aggiungere byte in un file
- copiare file con shutil
- verificare l’integrità con SHA-256
Queste tecniche sono molto utili in progetti reali, soprattutto quando lavori con immagini, documenti, archivi o dati esportati da applicazioni esterne.
Approfondisci con risorse ufficiali
- pathlib — documentazione ufficiale Python: gestione moderna dei percorsi e dei file
- io — flussi di input/output in Python
- hashlib — funzioni di hashing sicure
- shutil — operazioni ad alto livello su file e directory
- open() — funzione built-in per apertura dei file
Se vuoi, nel prossimo tutorial posso mostrarti un approfondimento su come leggere e modificare immagini in Python oppure su come salvare dati binari strutturati con il modulo struct.
