+\subsection{Input/output binario}
+\label{sec:file_binary_io}
+
+La prima modalità di input/output non formattato ricalca quella della
+interfaccia dei file descriptor, e provvede semplicemente la scrittura e
+la lettura dei dati da un buffer verso un file e viceversa. In generale
+questa è la modalità che si usa quando si ha a che fare con dati non
+formattati. Le due funzioni che si usano per l'I/O binario sono:
+\begin{functions}
+ \headdecl{stdio.h}
+ \funcdecl{size\_t fread(void * ptr, size\_t size,
+ size\_t nmemb, FILE * stream)}
+ \funcdecl{size\_t fwrite(const void *
+ ptr, size\_t size, size\_t nmemb, FILE * stream)}
+
+ Le funzioni rispettivamente leggono e scrivono \param{nmemb} elementi
+ di dimensione \param{size} dal buffer \param{ptr} al file \param{stream}.
+
+ Entrambe le funzioni ritornano il numero di elementi letti o scritti,
+ in caso di errore o fine del file viene restituito un numero di
+ elementi inferiore al richiesto.
+\end{functions}
+
+In genere si usano queste funzioni quando si devono trasferire su file
+blocchi di dati binari in maniera compatta e veloce; un primo caso di uso
+tipico è quello in cui si salva un vettore (o un certo numero dei suoi
+elementi) con una chiamata del tipo:
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+int WriteVect(FILE * stream, double * vec, size_t nelem)
+{
+ int size, nread;
+ size = sizeof(*vec);
+ if ( (nread = fwrite(vec, size, nelem, stream)) != nelem) {
+ perror("Write error");
+ }
+ return nread;
+}
+\end{lstlisting}
+in questo caso devono essere specificate le dimensioni di ciascun
+elemento ed il numero di quelli che si vogliono scrivere. Un secondo
+caso è invece quello in cui si vuole trasferire su file una struttura;
+si avrà allora una chiamata tipo:
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+struct histogram {
+ int nbins;
+ double max, min;
+ double * bin;
+} histo;
+
+int WriteStruct(FILE * stream, struct histogram * histo, size_t nelem)
+{
+ if ( fwrite(vec, sizeof(*histo), 1, stream) !=1) {
+ perror("Write error");
+ }
+ return nread;
+}
+\end{lstlisting}
+in cui si specifica la dimensione dell'intera struttura ed un solo
+elemento.
+
+In realtà quello che conta nel trasferimento dei dati sono le dimensioni
+totali, che sono sempre pari al prodotto \func{size * nelem}; la sola
+differenza è che le funzioni non ritornano il numero di byte scritti,
+ma il numero di elementi.
+
+La funzione \func{fread} legge sempre un numero intero di elementi, se
+incontra la fine del file l'oggetto letto parzialmente viene scartato
+(lo stesso avviene in caso di errore). In questo caso la posizione dello
+stream viene settata alla fine del file (e non a quella corrispondente
+alla quantità di dati letti).
+
+In caso di errore (o fine del file per \func{fread}) entrambe le
+funzioni restituiscono il numero di oggetti effettivamente letti o
+scritti, che sarà inferiore a quello richiesto. Contrariamente a quanto
+avviene per i file descriptor, questo segnala una condizione di errore e
+occorrerà usare \func{feof} e \func{ferror} per stabilire la natura del
+problema.
+
+Benché queste funzioni assicurino la massima efficienza per il
+salvataggio dei dati, i dati memorizzati attraverso di esse presentano
+lo svantaggio di dipendere strettamente dalla piattaforma di sviluppo
+usata ed in genere possono essere riletti senza problemi solo dallo
+stesso programma che li ha prodotti.
+
+Infatti diversi compilatori possono eseguire ottimizzazioni diverse
+delle strutture dati e alcuni compilatori (come il \cmd{gcc}) possono
+anche scegliere se ottimizzare l'occupazione di spazio, impacchettando
+più strettamente i dati, o la velocità inserendo opportuni
+\textit{padding} per l'allineamento dei medesimi generando quindi output
+binari diversi. Inoltre altre incompatibilità si possono presentare
+quando entrano in gioco differenze di architettura hardware, come la
+dimensione del bus o la modalità di ordinamento dei bit o il formato
+delle variabili in floating point.
+
+Per questo motivo quando si usa l'input/output binario occorre sempre
+essere prendere le opportune precauzioni (in genere usare un formato di
+più alto livello che permetta di recuperare l'informazione completa),
+per assicurarsi che versioni diverse del programma siano in grado di
+rileggere i dati tenendo conto delle eventuali differenze.
+
+Le \acr{glibc} definiscono altre due funzioni per l'I/O binario, che
+evitano il lock implicito dello stream, usato per dalla librerie per la
+gestione delle applicazioni multi-thread (si veda
+\secref{sec:file_stream_thread} per i dettagli).
+
+\begin{functions}
+ \headdecl{stdio.h}
+
+ \funcdecl{size\_t fread\_unlocked(void * ptr, size\_t size, size\_t
+ nmemb, FILE * stream)}
+
+ \funcdecl{size\_t fwrite\_unlocked(const void * ptr, size\_t size,
+ size\_t nmemb, FILE * stream)}
+
+ Le funzioni sono identiche alle analoghe \func{fread} e \func{fwrite}
+ ma non acquisiscono il lock implicito sullo stream.
+\end{functions}
+\noindent entrambe le funzioni sono estensioni GNU previste solo dalle
+ \acr{glibc}.