X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=filestd.tex;h=d46f965842ea2895924ef4e112bc8224a3d565b7;hp=c51220daac6bde26ed2437f1e8bb2f3f2740a492;hb=56a7803a5e9f18850548c186b7aa9813b071107d;hpb=aad74b105a8ff157f0d4420668f1182d8a356615;ds=sidebyside diff --git a/filestd.tex b/filestd.tex index c51220d..d46f965 100644 --- a/filestd.tex +++ b/filestd.tex @@ -30,13 +30,12 @@ Come pi basso livello, che non provvede nessuna forma di formattazione dei dati e nessuna forma di bufferizzazione per ottimizzare le operazioni di I/O. -In \textit{Advanced Programming in the Unix Environment} Stevens descrive una -serie di test sull'influenza delle dimensioni del blocco di dati (il parametro -\param{buf} di \func{read} e \func{write}) nell'efficienza nelle operazioni di -I/O con i file descriptor, evidenziando come le prestazioni ottimali si -ottengano a partire da dimensioni del buffer dei dati pari a quelle dei -blocchi del filesystem (il valore dato dal campo \var{st\_blksize} di -\var{fstat}). +In \cite{APUE} Stevens descrive una serie di test sull'influenza delle +dimensioni del blocco di dati (il parametro \param{buf} di \func{read} e +\func{write}) nell'efficienza nelle operazioni di I/O con i file descriptor, +evidenziando come le prestazioni ottimali si ottengano a partire da dimensioni +del buffer dei dati pari a quelle dei blocchi del filesystem (il valore dato +dal campo \var{st\_blksize} di \var{fstat}). Se il programmatore non si cura di effettuare le operazioni in blocchi di dimensioni adeguate, le prestazioni sono inferiori. La caratteristica @@ -209,10 +208,10 @@ corrente in uno stream. \subsection{Apertura e chiusura di uno stream} \label{sec:file_fopen} -Le funzioni che si possono usare per aprire uno stream sono solo -tre\footnote{\func{fopen} e \func{freopen} fanno parte dello standard - ANSI C, \func{fdopen} è parte dello standard POSIX.1.}, i loro -prototipi sono: +Le funzioni che si possono usare per aprire uno stream sono solo tre: +\func{fopen}, \func{fdopen} e \func{freopen}\footnote{\func{fopen} e + \func{freopen} fanno parte dello standard ANSI C, \func{fdopen} è parte + dello standard POSIX.1.}, i loro prototipi sono: \begin{functions} \headdecl{stdio.h} \funcdecl{FILE *fopen(const char *path, const char *mode)} @@ -475,6 +474,7 @@ 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: +\footnotesize \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} int WriteVect(FILE *stream, double *vec, size_t nelem) { @@ -486,10 +486,12 @@ int WriteVect(FILE *stream, double *vec, size_t nelem) return nread; } \end{lstlisting} +\normalsize 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: +\footnotesize \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} struct histogram { int nbins; @@ -505,6 +507,7 @@ int WriteStruct(FILE *stream, struct histogram *histo, size_t nelem) return nread; } \end{lstlisting} +\normalsize in cui si specifica la dimensione dell'intera struttura ed un solo elemento. @@ -756,7 +759,6 @@ capo della tastiera), ma \func{gets} sostituisce \verb|\n| con uno zero, mentre \func{fgets} aggiunge uno zero dopo il \textit{newline}, che resta dentro la stringa. Se la lettura incontra la fine del file (o c'è un errore) viene restituito un \macro{NULL}, ed il buffer \param{buf} non viene toccato. - L'uso di \func{gets} è deprecato e deve essere assolutamente evitato; la funzione infatti non controlla il numero di byte letti, per cui nel caso la stringa letta superi le dimensioni del buffer, si avrà un @@ -957,11 +959,7 @@ dell'alternativa: La parte più complessa di queste funzioni è il formato della stringa \param{format} che indica le conversioni da fare, da cui poi deriva il numero -dei parametri che dovranno essere passati a seguire. La stringa è costituita -da caratteri normali (tutti eccetto \texttt{\%}), che vengono passati -invariati all'output, e da direttive di conversione, in cui devono essere -sempre presenti il carattere \texttt{\%}, che introduce la direttiva, ed uno -degli specificatori di conversione (riportati in \ntab) che la conclude. +dei parametri che dovranno essere passati a seguire. \begin{table}[htb] \centering @@ -1007,6 +1005,32 @@ degli specificatori di conversione (riportati in \ntab) che la conclude. \label{tab:file_format_spec} \end{table} +La stringa è costituita da caratteri normali (tutti eccetto \texttt{\%}), che +vengono passati invariati all'output, e da direttive di conversione, in cui +devono essere sempre presenti il carattere \texttt{\%}, che introduce la +direttiva, ed uno degli specificatori di conversione (riportati in +\tabref{tab:file_format_spec}) che la conclude. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|p{10cm}|} + \hline + \textbf{Valore} & \textbf{Significato}\\ + \hline + \hline + \cmd{\#} & Chiede la conversione in forma alternativa. \\ + \cmd{0} & La conversione è riempita con zeri alla sinistra del valore.\\ + \cmd{-} & La conversione viene allineata a sinistra sul bordo del campo.\\ + \cmd{' '}& Mette uno spazio prima di un numero con segno di valore + positivo\\ + \cmd{+} & Mette sempre il segno ($+$ o $-$) prima di un numero.\\ + \hline + \end{tabular} + \caption{I valori dei flag per il formato di \func{printf}} + \label{tab:file_format_flag} +\end{table} + Il formato di una direttiva di conversione prevede una serie di possibili elementi opzionali oltre al \cmd{\%} e allo specificatore di conversione. In generale essa è sempre del tipo: @@ -1032,26 +1056,6 @@ questo ordine: \end{itemize*} -\begin{table}[htb] - \centering - \footnotesize - \begin{tabular}[c]{|l|p{10cm}|} - \hline - \textbf{Valore} & \textbf{Significato}\\ - \hline - \hline - \cmd{\#} & Chiede la conversione in forma alternativa. \\ - \cmd{0} & La conversione è riempita con zeri alla sinistra del valore.\\ - \cmd{-} & La conversione viene allineata a sinistra sul bordo del campo.\\ - \cmd{' '}& Mette uno spazio prima di un numero con segno di valore - positivo\\ - \cmd{+} & Mette sempre il segno ($+$ o $-$) prima di un numero.\\ - \hline - \end{tabular} - \caption{I valori dei flag per il formato di \func{printf}} - \label{tab:file_format_flag} -\end{table} - Dettagli ulteriori sulle varie opzioni possono essere trovati nella man page di \func{printf} e nella documentazione delle \acr{glibc}. @@ -1294,9 +1298,10 @@ pu errore.} \end{functions} -In Linux, a partire dalle glibc 2.1, sono presenti anche le funzioni -\func{fseeko} e \func{ftello}, assolutamente identiche alle precedenti ma con -argomenti di tipo \type{off\_t} anziché di tipo \type{long int}. +In Linux, a partire dalle glibc 2.1, sono presenti anche le due funzioni +\func{fseeko} e \func{ftello}, che assolutamente identiche alle precedenti +\func{fseek} e \func{ftell} ma hanno argomenti di tipo \type{off\_t} anziché +di tipo \type{long int}. @@ -1392,7 +1397,7 @@ suo prototipo da \param{mode}, usando \param{buf} come buffer di lunghezza \param{size}. \bodydesc{Restituisce zero in caso di successo, ed un valore qualunque in - caso di errore.} + caso di errore, nel qual caso \var{errno} viene settata opportunamente.} \end{prototype} La funzione permette di controllare tutti gli aspetti della bufferizzazione; @@ -1413,18 +1418,11 @@ pu Dato che la procedura di allocazione manuale è macchinosa, comporta dei rischi (come delle scritture accidentali sul buffer) e non assicura la scelta delle dimensioni ottimali, è sempre meglio lasciare allocare il buffer alle funzioni -di librerie, che sono in grado di farlo in maniera ottimale e trasparente +di libreria, che sono in grado di farlo in maniera ottimale e trasparente all'utente (in quanto la disallocazione avviene automaticamente). Inoltre siccome alcune implementazioni usano parte del buffer per mantenere delle informazioni di controllo, non è detto che le dimensioni dello stesso -coincidano con le dimensioni con cui viene effettuato l'I/O. - -Per evitare che \func{setvbuf} setti il buffer basta passare un valore -\macro{NULL} per \param{buf} e la funzione ignorerà il parametro \param{size} -usando il buffer allocato automaticamente dal sistema. Si potrà comunque -modificare la modalità di bufferizzazione, passando in \param{mode} uno degli -opportuni valori elencati in \ntab. Qualora si specifichi la modalità non -bufferizzata i valori di \param{buf} e \param{size} vengono sempre ignorati. +coincidano con quelle su cui viene effettuato l'I/O. \begin{table}[htb] \centering @@ -1439,11 +1437,19 @@ bufferizzata i valori di \param{buf} e \param{size} vengono sempre ignorati. \macro{\_IOFBF} & \textit{fully buffered}\\ \hline \end{tabular} - \label{tab:file_stream_buf_mode} \caption{Valori del parametro \param{mode} di \func{setvbuf} per il settaggio delle modalità di bufferizzazione.} + \label{tab:file_stream_buf_mode} \end{table} +Per evitare che \func{setvbuf} setti il buffer basta passare un valore +\macro{NULL} per \param{buf} e la funzione ignorerà il parametro \param{size} +usando il buffer allocato automaticamente dal sistema. Si potrà comunque +modificare la modalità di bufferizzazione, passando in \param{mode} uno degli +opportuni valori elencati in \tabref{tab:file_stream_buf_mode}. Qualora si +specifichi la modalità non bufferizzata i valori di \param{buf} e \param{size} +vengono sempre ignorati. + Oltre a \func{setvbuf} le \acr{glibc} definiscono altre tre funzioni per la gestione della bufferizzazione di uno stream: \func{setbuf}, \func{setbuffer} e \func{setlinebuf}, i loro prototipi sono: