Si prosegue con le questioni relative alla bufferizzazione
[gapil.git] / filestd.tex
1 \chapter{I file: l'interfaccia standard ANSI C}
2 \label{cha:files_std_interface}
3
4 Esamineremo in questo capitolo l'interfaccia standard ANSI C per i file,
5 quella che viene comunemente detta interfaccia degli \textit{stream}.
6 Dopo una breve sezione introduttiva tratteremo le funzioni base per la
7 gestione dell'input/output, mentre tratteremo le caratteristiche più avanzate
8 dell'interfaccia nell'ultima sezione.
9
10
11 \section{Introduzione}
12 \label{sec:file_stream_intro}
13
14 Come visto in \capref{cap:file_unix_interface} le operazioni di I/O sui file
15 sono gestibili direttamente a basso livello con l'interfaccia standard unix
16 che ricorre direttamente alle system call messe a disposizione dal kernel.
17
18 Questa interfaccia però non provvede le funzionalità previste dallo standard
19 ANSI C che invece sono realizzate attraverso opportune funzioni di libreria,
20 che vengono a costituire il nucleo essenziale\footnote{queste funzioni sono
21   state implementate la prima volta da Ritchie nel 1976 e da allora sono
22   rimaste sostanzialmente immutate.} delle \acr{glibc}.
23
24
25 \subsection{I \textit{file stream}}
26 \label{sec:file_stream}
27
28 Come più volte ribadito l'interfaccia dei file descriptor è una interfaccia di
29 basso livello, che non provvede nessuna forma di formattazione dei dati, e
30 nessuna forma di bufferizzazione per ottimizzare le operazioni di I/O.
31
32 In \textit{Advanced Programming in the Unix Environment} Stevens esegue un
33 raffronto dell'influenza delle dimensioni del blocco di dati (il parametro
34 \param{buf} di \func{read} e \func{write}) nell'efficienza nelle operazioni di
35 I/O con i file descriptor, evidenziando come le prestazioni ottimali si
36 ottengano quando il buffer dei dati ha la stessa dimensione dei blocchi del
37 filesystem (il valore dato dal campo \var{st\_blksize} di \var{fstat}).
38
39 In questo caso se il programmatore non si cura di effettuare le operazioni in
40 blocchi di dimensioni adeguate, le prestazioni possono deteriorarsi in maniera
41 evidente. L'interfaccia degli stream provvede da sola la gestione dei dettagli
42 della bufferizzazione e dell'esecuzione delle operazioni di lettura e
43 scrittura effettive in blocchi di dimensioni appropriate all'ottenimento della
44 massima efficienza.
45
46 Per questo motivo l'interfaccia viene chiamata anche interfaccia dei
47 \textit{file stream}, dato che non è più necessario doversi preoccupare di
48 gestire i dettagli della comunicazione con il tipo di hardware sottostante, ed
49 esso può essere sempre considerato come composto da un flusso (da cui il nome
50 \textit{stream}) continuo di dati.
51
52 Ma a parte le particolarità della gestione delle operazioni di lettura e
53 scrittura, i file stream restano del tutto equivalenti ai file descriptor sui
54 quali sono basati, ed in particolare vale quanto visto in
55 \secref{sec:file_sharing} a proposito dell'accesso condiviso ed in
56 \secref{sec:file_access_control} per il controllo di accesso.
57
58
59 \subsection{Gli oggetti \type{FILE}}
60 \label{sec:file_FILE}
61
62 Per ragioni storiche la struttura di dati che rappresenta un stream è stata
63 chiamata \type{FILE}, questi oggetti sono creati dalle funzioni di libreria e
64 contengono tutte le informazioni necessarie a gestire le operazioni sugli
65 stream, come la posizione corrente, lo stato del buffer e degli indicatori di
66 stato e di fine del file.
67
68 Per questo motivo gli utenti non devono mai utilizzare direttamente o allocare
69 queste strutture, ma usare sempre puntatori del tipo \type{FILE *} ottenuti
70 dalla libreria stessa (tanto che in certi casi il termine di puntatore a file
71 è diventato sinonimo di stream). 
72
73 Tutte le funzioni della libreria che operano sui file accettano come parametri
74 solo variabili di questo tipo, che diventa accessibile includendo l'header
75 file \file{stdio.h}.
76
77
78
79 \subsection{Gli stream standard}
80 \label{sec:file_std_stream}
81
82 Ai tre file descriptor standard (vedi \secref{sec:file_std_descr}) aperti per
83 ogni processo, corrispondono altrettanti stream predefiniti per ogni processo,
84 che rappresentano i canali standard di input/output prestabiliti; anche questi
85 tre stream sono definiti nell'header \file{stdio.h} e sono:
86
87 \begin{itemize}
88 \item \var{FILE * stdin} Lo \textit{standard input} cioè lo stream da cui
89   il processo riceve ordinariamente i dati in ingresso. Normalmente è associato
90   dalla shell all'input del terminale e prende i caratteri dalla tastiera.
91 \item \var{FILE * stdout} Lo \textit{standard input} cioè lo stream su cui
92   il processo invia ordinariamente i dati in uscita. Normalmente è associato
93   dalla shell all'output del terminale e scrive sullo schermo.
94 \item \var{FILE * stderr} Lo \textit{standard input} cioè lo stream su cui
95   il processo è supposto inviare i messaggi di errore. Normalmente anch'esso
96   è associato dalla shell all'output del terminale e scrive sullo schermo.
97 \end{itemize}
98
99 Nelle \acr{glibc} \var{stdin}, \var{stdout} e \var{stderr} sono effettivamente
100 tre variabili che possono essere usate come tutte le altre, ad esempio si può
101 effettuare una redirezione dell'output di un programma con il semplice codice:
102 \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
103     fclose (stdout);
104     stdout = fopen ("standard-output-file", "w");
105 \end{lstlisting}
106 ma in altri sistemi possono essere definite come macro, e deve essere pertanto
107 usata \func{freopen}.
108
109
110 \subsection{Le modalità di bufferizzazione}
111 \label{sec:file_buffering}
112
113 La bufferizzazione è una delle caratteristiche principali della interfaccia
114 degli stream; lo scopo è quello di ridurre al minimo il numero di system call
115 (\func{read} o \func{write}) eseguite nelle operazioni di input/output. Questa
116 funzionalità è assicurata automaticamente dalla libreria, ma costituisce anche
117 una degli aspetti più comunemente fraintesi.
118
119 I caratteri che vengono scritti su uno stream normalmente vengono accumulati e
120 poi trasmessi in blocco in maniera asincrona (quello che viene chiamato il
121 \textit{flush} dei dati) quando il buffer è pieno, questo tipo di
122 comportamento vale anche per la lettura (cioè dal file viene letto un blocco
123 di dati, anche se se ne sono richiesti una quantità inferiore).  
124
125 Se si sta facendo dell'input/output interattivo però bisogna tenere presente
126 le caratteristiche con cui viene effettuata la bufferizzazione, pena il
127 rischio di non vedere apparire l'output o di ottenere degli effetti
128 indesiderati nella visualizzazione.
129
130 Per questo motivo, la libreria definisce tre distinte modalità di
131 bufferizzazione, adatte a situazioni diverse, di cui occorre essere ben
132 consapevoli:
133 \begin{itemize}
134 \item \textit{unbuffered}: in questa modalità i caratteri non sono
135   bufferizzati e vengono trasmessi individualmente al file non appena
136   possibile (effettuando immediatamente una \func{write}).
137 \item \textit{line buffered}: in questo caso i caratteri vengono trasmessi
138   al file in blocco ogni volta che viene incontrato un carattere di
139   \textit{newline} (il carattere ASCII \verb|\n|).
140 \item \textit{fully buffered}: in questo caso i caratteri vengono trasmessi da
141   e verso il file in blocchi di dimensione opportuna.
142 \end{itemize}
143
144 Lo standard ANSI C specifica soltanto che lo standard output e lo standard
145 input siano aperti in modalità \textit{fully buffered} quando non fanno
146 riferimento ad un dispositivo interattivo, e che lo standard error non sia mai
147 aperto in modalità \textit{fully buffered}.
148
149 Linux, come BSD e SVr4, specifica il comportamento di default in maniera più
150 precisa, e cioè impone che lo standard error sia sempre \textit{unbuffered}
151 (in modo che i messaggi di errore siano mostrati il più rapidamente possibile)
152 e che standard input e standard output siano aperti in modalità \textit{line
153   buffered} quando sono associati ad un terminale (od altro dispositivo
154 interattivo) ed in modalità \textit{fully buffered} altrimenti.
155
156 Il comportamento specificato per standard input e standard output vale anche
157 per tutti i nuovi stream aperti da un processo; la selezione comunque avviene
158 automaticamente, e la libreria apre lo stream nella modalità più opportuna a
159 seconda file o al dispositivo scelto.
160
161 La modalità \textit{line buffered} è quella passibile di maggiori
162 fraintendimenti, la descrizione che se ne è data infatti non è precisa, dato
163 che le dimensioni del buffer di I/O sono fisse e se le si eccedono può essere
164 effettuato un \textit{flush} dei dati anche prima che si sia inviato un
165 carattere di \textit{newline}.
166
167
168
169
170 \section{Funzioni base}
171 \label{sec:file_ansi_base_func}
172
173 Esamineremo in questa sezione le funzioni base dell'interfaccia degli stream,
174 analoghe a quelle di \secref{sec:file_base_func} per i file descriptor. In
175 particolare vedremo come aprire, leggere, scrivere e cambiare la posizione
176 corrente in uno stream.
177
178
179 \subsection{Apertura di uno stream}
180 \label{sec:file_fopen}
181
182
183 \subsection{Lettura e scrittura su uno stream}
184 \label{sec:file_io}
185
186
187 \subsection{Posizionamento su uno stream}
188 \label{sec:file_fseek}
189
190
191 \subsection{Input/output binario}
192 \label{sec:file_binary_io}
193
194
195 \subsection{Input/output di linea}
196 \label{sec:file_line_io}
197
198
199 \subsection{Input/output formattato}
200 \label{sec:file_formatted_io}
201
202
203 \subsection{Chiusura di uno stream}
204 \label{sec:file_fclose}
205
206
207 \section{Funzioni avanzate}
208 \label{sec:file_stream_adv_func}
209
210
211 \subsection{Il controllo della bufferizzazione}
212 \label{sec:file_buffering-ctrl}
213
214
215 \subsection{Dettagli dell'implementazione}
216 \label{sec:file_stream_details}
217
218
219 \subsection{File temporanei}
220 \label{sec:file_temp_file}
221
222
223 \subsection{Efficienza}
224 \label{sec:file_stream_efficiency}
225
226
227
228
229
230
231
232
233