\subsection{I \textit{file stream}}
\label{sec:file_stream}
-Come più volte ribadito l'interfaccia dei file descriptor è un'interfaccia di
+Come più volte ribadito, l'interfaccia dei file descriptor è un'interfaccia di
basso livello, che non provvede nessuna forma di formattazione dei dati e
nessuna forma di bufferizzazione per ottimizzare le operazioni di I/O.
\subsection{Le modalità di bufferizzazione}
\label{sec:file_buffering}
-La bufferizzazione è una delle caratteristiche principali della
-interfaccia degli stream; lo scopo è quello di ridurre al minimo il
-numero di system call (\func{read} o \func{write}) eseguite nelle
-operazioni di input/output. Questa funzionalità è assicurata
-automaticamente dalla libreria, ma costituisce anche uno degli aspetti
-più comunemente fraintesi, in particolare per quello che riguarda
-l'aspetto della scrittura dei dati sul file.
-
-I caratteri che vengono scritti su uno stream normalmente vengono
-accumulati in un buffer e poi trasmessi in blocco in maniera asincrona
-rispetto alla scrittura (quello che viene chiamato lo \textsl{scarico}
-dei dati, dall'inglese \textit{flush}) tutte le volte che il buffer
-viene riempito. Un comportamento analogo avviene anche in lettura (cioè
-dal file viene letto un blocco di dati, anche se se ne sono richiesti
-una quantità inferiore), ma la cosa ovviamente ha rilevanza inferiore,
-dato che i dati letti sono sempre gli stessi; in caso di scrittura
-invece, quando si ha un accesso contemporaneo allo stesso file (ad
-esempio da parte di un altro processo) si potranno vedere solo le parti
-effettivamente scritte, e non quelle ancora presenti nel buffer.
+La bufferizzazione è una delle caratteristiche principali dell'interfaccia
+degli stream; lo scopo è quello di ridurre al minimo il numero di system call
+(\func{read} o \func{write}) eseguite nelle operazioni di input/output. Questa
+funzionalità è assicurata automaticamente dalla libreria, ma costituisce anche
+uno degli aspetti più comunemente fraintesi, in particolare per quello che
+riguarda l'aspetto della scrittura dei dati sul file.
+
+I caratteri che vengono scritti su uno stream normalmente vengono accumulati
+in un buffer e poi trasmessi in blocco in maniera asincrona rispetto alla
+scrittura (quello che viene chiamato lo \textsl{scarico} dei dati,
+dall'inglese \textit{flush}) tutte le volte che il buffer viene riempito. Un
+comportamento analogo avviene anche in lettura (cioè dal file viene letto un
+blocco di dati, anche se ne sono richiesti una quantità inferiore), ma la cosa
+ovviamente ha rilevanza inferiore, dato che i dati letti sono sempre gli
+stessi; in caso di scrittura invece, quando si ha un accesso contemporaneo
+allo stesso file (ad esempio da parte di un altro processo) si potranno vedere
+solo le parti effettivamente scritte, e non quelle ancora presenti nel buffer.
Allo stesso modo, se si sta facendo dell'input/output interattivo
bisognerà tenere presente le caratteristiche delle operazioni di scarico
La modalità \textit{line buffered} è quella che necessita di maggiori
chiarimenti e attenzioni per quel che concerne il suo funzionamento. Come già
accennato nella descrizione, \emph{di norma} i dati vengono inviati al kernel
-alla ricezione di un carattere di a capo; questo non è vero in tutti i casi,
-infatti, dato che le dimensioni del buffer usato dalle librerie sono fisse, se
-le si eccedono si può avere uno scarico dei dati anche prima che sia stato
-inviato un carattere di \textit{newline}.
+alla ricezione di un carattere di \textsl{a capo} (\textit{newline}); questo
+non è vero in tutti i casi, infatti, dato che le dimensioni del buffer usato
+dalle librerie sono fisse, se le si eccedono si può avere uno scarico dei dati
+anche prima che sia stato inviato un carattere di \textit{newline}.
Un secondo punto da tenere presente, particolarmente quando si ha a che fare
-con I/O interattivo, è che quando si effettua una lettura su uno stream che
-comporta l'accesso al kernel\footnote{questo vuol dire sempre se lo stream da
- cui si legge è in modalità \textit{unbuffered}.} viene anche eseguito lo
-scarico di tutti i buffer degli stream in scrittura.
+con I/O interattivo, è che quando si effettua una lettura da uno stream che
+comporta l'accesso al kernel\footnote{questo vuol dire che lo stream da cui si
+ legge è in modalità \textit{unbuffered}.} viene anche eseguito lo scarico di
+tutti i buffer degli stream in scrittura.
In \secref{sec:file_buffering_ctrl} vedremo come la libreria definisca delle
opportune funzioni per controllare le modalità di bufferizzazione e lo scarico
\textit{append mode}, l'accesso viene posto in lettura e scrittura. \\
\hline
\texttt{b} & specifica che il file è binario, non ha alcun effetto. \\
- \texttt{x} & la apertura fallisce se il file esiste già. \\
+ \texttt{x} & l'apertura fallisce se il file esiste già. \\
\hline
\end{tabular}
\caption{Modalità di apertura di uno stream dello standard ANSI C che
\item\textsl{a caratteri} in cui si legge/scrive un carattere alla
volta (con la bufferizzazione gestita automaticamente dalla libreria),
vedi \secref{sec:file_char_io}.
-\item\textsl{di linea} in cui si legge/scrive una linea (terminata dal
- carattere di newline \verb|\n|) alla volta, vedi
- \secref{sec:file_line_io}.
+\item\textsl{di linea} in cui si legge/scrive una linea alla volta (terminata
+ dal carattere di newline \verb|'\n'|), vedi \secref{sec:file_line_io}.
\end{enumerate*}
ed inoltre la modalità di input/output formattato.
\begin{prototype}{stdio.h}{void clearerr(FILE *stream)}
Cancella i flag di errore ed end-of-file di \param{stream}.
\end{prototype}
-\noindent in genere si usa questa funziona una volta che si sia identificata e
+\noindent in genere si usa questa funzione una volta che si sia identificata e
corretta la causa di un errore per evitare di mantenere i flag attivi, così da
poter rilevare una successiva ulteriore condizione di errore. Di questa
funzione esiste una analoga \func{clearerr\_unlocked} che non esegue il blocco
double *bin;
} histo;
-int WriteStruct(FILE *stream, struct histogram *histo, size_t nelem)
+int WriteStruct(FILE *stream, struct histogram *histo)
{
if ( fwrite(vec, sizeof(*histo), 1, stream) !=1) {
perror("Write error");
La funzione viene usata dal comando \cmd{sync} quando si vuole forzare
esplicitamente lo scarico dei dati su disco, o dal demone di sistema
\cmd{update} che esegue lo scarico dei dati ad intervalli di tempo fissi: il
-valore tradizionale per l'update dei dati è ogni 30 secondi, ma in Linux era
-di 5 secondi; con le nuove versioni poi, è il kernel che si occupa
-direttamente di tutto quanto.
+valore tradizionale, usato da BSD, per l'update dei dati è ogni 30 secondi, ma
+in Linux ilvalore utilizzato è di 5 secondi; con le nuove versioni poi, è il
+kernel che si occupa direttamente di tutto quanto.
Quando si vogliono scaricare soltanto i dati di un file (ad esempio essere
sicuri che i dati di un database sono stati registrati su disco) si possono
Entrambe le funzioni forzano la sincronizzazione col disco di tutti i dati del
file specificato, ed attendono fino alla conclusione delle operazioni;
-\func{fsync} forza anche la sincronizzazione dei metadata dell'inode (i dati
-di \var{fstat} come i tempi del file).
+\func{fsync} forza anche la sincronizzazione dei metadati del file (che
+riguardano sia le modifiche alle tabelle di allocazione dei settori, che gli
+altri dati contenuti nell'inode che si leggono con \var{fstat} come i tempi
+del file).
Si tenga presente che questo non comporta la sincronizzazione della
directory che contiene il file (e scrittura della relativa voce su