File di Testo e File Binari in Linguaggio C

Concetti Chiave
  • La libreria standard del C supporta due tipologie di file: i file di testo e i file binari.
  • I file di testo sono formati da sequenze di caratteri leggibili, mentre i file binari contengono dati in formato grezzo.
  • Un file di testo è suddiviso per righe e potrebbe contenere un carattere di fine riga.
  • I file binari non sono suddivisi in righe nè tantomeno hanno un carattere che indica il fine file.
  • In generale, se non si possono fare assunzioni sul tipo di file che un programma dovrà manipolare, conviene sempre trattare i file come file binari.

File di Testo e File Binari

La libreria standard del linguaggio C supporta due tipologie di file: i file di testo e i file binari.

In un file di testo, i byte che compongono il file rappresentano singoli caratteri e, infatti, un file di testo può essere letto da un essere umano attraverso un editor di testo. Il codice sorgente di un programma C, ad esempio, è contenuto in un file con estensione .c ed è a tutti gli effetti un file di testo.

In un file binario, d'altro canto, i byte possono rappresentare dati qualunque, da tipi semplici come numeri interi o in virgola mobile, oppure dati complessi come strutture e array. I file binari non possono essere letti direttamente da un editor di testo, in quanto il loro contenuto non è stampabile. Ad esempio, un file eseguibile è un file binario in quanto contiene le istruzioni macchina necessarie per essere eseguite da un processore.

I file di testo possiedono due caratteristiche fondamentali:

  • I file di testo sono divisi per righe o linee di testo.

    Ciascuna riga di un file di testo normalmente termina con una sequenza di caratteri che indicano il ritorno a capo. Questa sequenza di caratteri può variare a seconda del sistema operativo: ad esempio, nei sistemi Unix/Linux si utilizza il carattere di nuova linea (\n), mentre nei sistemi Windows si utilizza la sequenza di caratteri \r\n (ossia ritorno a capo più nuova riga).

    Pertanto, quando si scrive o legge un file di testo dal linguaggio C bisogna tener presente di questa differenza e gestire correttamente i caratteri di fine riga.

  • I file di testo possono contenere uno speciale carattere di fine del file o EOF (End Of File).

    Alcuni sistemi operativi richiedono o consentono che un particolare carattere ASCII sia usato come indicatore di fine file. Ad esempio, nei sistemi Windows si utilizza il carattere 0x1A (che corrisponde alla sequenza CTRL+Z). In realtà, sotto Windows non vi è nessun obbligo di inserire il carattere di fine file al termine del file ma, se esso è presente, tutti i byte che si trovano dopo di esso vengono ignorati. Essi però verranno comunque considerati nel computo della dimensione del file stesso.

    CTRL+Z è un retaggio del vecchio sistema operativo MS-DOS che a sua volta ha mutuato questa convenzione da un altro sistema operativo ancora più vecchio: il sistema CP/M.

    I sistemi UNIX, d'altro canto, così come Linux, non hanno un vero e proprio carattere di fine file. Esiste il carattere EOF (End Of File), che è un concetto logico piuttosto che un carattere fisico presente nel file. Esso viene adoperato quando si legge da un dispositivo piuttosto che da un file, pertanto non è necessario includere un carattere di fine file nei file di testo.

I file binari non sono suddivisi in righe nè tantomeno hanno un carattere che indica il fine file. In essi, tutti i byte sono trattati come dati grezzi.

Quando si scrivono dati su di un file bisogna scegliere se salvare tali dati in formato testo o in formato binario. Per comprendere la differenza, supponiamo di voler salvare un numero: 8192.

Se lo salviamo come dato testuale, una scelta plausibile potrebbe essere quella di adoperare la codifica ASCII. In questo caso, il numero 8192 verrebbe convertito nella sua rappresentazione testuale, che è la stringa "8192". Questa stringa verrebbe memorizzata come:

+----------+----------+----------+----------+
| 00111000 | 00110001 | 00111001 | 00110010 |
+----------+----------+----------+----------+
    '8'         '1'        '9'        '2'

Il nostro numero occuperebbe quindi quattro byte.

Viceversa, se scegliamo di salvarlo in binario, il numero 8192 verrebbe prima convertito in una sequenza di 16 bit:

0010000000000000

Dopodiché, supponendo di memorizzare il numero in formato little-endian, i byte verrebbero memorizzati nell'ordine seguente:

00000000 | 00100000

Quindi, con il formato binario, il numero 8192 occuperebbe due byte, la metà del caso testuale.

Quando si scrive un programma in C che scrive e legge dei file bisogna tenere conto, quindi, se si sta lavorando con file di testo o file binari, poiché le modalità di accesso e di gestione dei dati sono diverse. Un programma che mostra il contenuto di un file a schermo, ad esempio, probabilmente avrà a che fare con file di testo. Un programma che si occupa di copiare file tra loro non può, invece, assumere che si tratti di file di testo ma dovrà considerare i file in questione come file binari qualunque. Del resto un file di testo è comunque pur sempre un file binario. Se questo programma facesse l'assunzione che si tratti di file di testo, probabilmente scarterebbe l'eventuale carattere di fine di file e gli eventuali caratteri che si trovano dopo di esso verrebbero ignorati.

In generale, se non si possono fare assunzioni sul tipo di file che un programma dovrà manipolare, conviene sempre trattare i file come file binari.