Gestire i file binari in Python in modo sicuro e pratico

by theArchitect
SHARE
Gestire i file binari in Python in modo sicuro e pratico
© Guida-HTML5.it

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 with per 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 pathlib a 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.

SHARE