Newsgroup: it.comp.lang.c
Titolo: Ma FILE, in realtà, che cos'è?

Salve,
sto studiando il C, cercando di capire quello che faccio.
Sto vedendo come leggere e scrivere su files,
ed ho incontrato il tipo FILE, contenuto in stdio.h.
Premetto che vengo da Java (si, lo so che passare da Java 
al C è abbastanza traumatico).
Però mi chiedo... Ma questo tipo, FILE, in realtà che
cos'è? Insomma, è uno struct?
Googlando (
http://www.cplusplus.com/reference/clibrary/cstdio/FILE/
)
ottengo la seguente definizione:
"This type of object identifies a stream and contains the information 
needed to control it [...]"
Che non si discosta molto da quello che dice la mia copia del K&R.
Però non mi risolve il problema... Insomma, questo FILE, in realtà,
che cos'è?
Grazie in anticipo,
Rzl

 realtÃ  che cos'Ãš? Insomma, Ãš uno struct?
Certo, è una struttura. Quando chiami "fopen"
ottieni un puntatore a un'istanza di quella
struttura che penserà il sistema operativo a
riservare, gestire e rendere disponibile quando
chiudi il file. Il tutto in modo trasparente.
Un tempo i compilatori che usavo permettevano pure
l'accesso ai membri e mi divertivo a vedere il
funzionamento. Ora non so se è possibile; da quando
ho scoperto che CGG controlla gli argomenti di
"printf" a livello di compilazione la mia vita è
cambiata e sono diventato diffidentissimo :D
-- 
Una volta ho chiesto la differenza tra l'incesto
e l'incendio. Non credo di aver capito troppo bene
perché dopo un po' ho dato fuoco a mia sorella.


Uhm. La mia box (Debian testing/squeeze) in /usr/include/stdio.h riporta:
------- 8< ------- 8< --------
#if !defined __FILE_defined && defined __need_FILE
/* Define outside of namespace so the C++ is happy.  */
struct _IO_FILE;
__BEGIN_NAMESPACE_STD
/* The opaque type of streams.  This is the definition used elsewhere.  */
typedef struct _IO_FILE FILE;
__END_NAMESPACE_STD
------- 8< ------- 8< --------
Boh?
Un'altra delle mie box, invece, che fa girare NetBSD 5.0.1, 
sembra essere molto, molto piu` chiara in merito:
------- 8< ------- 8< --------
typedef struct __sFILE {
        unsigned char *_p;      /* current position in (some) buffer */
        int     _r;             /* read space left for getc() */
        int     _w;             /* write space left for putc() */
        unsigned short _flags;  /* flags, below; this FILE is free if 0 */
        short   _file;          /* fileno, if Unix descriptor, else -1 */
        struct  __sbuf _bf;     /* the buffer (at least 1 byte, if !NULL) 
*/
        int     _lbfsize;       /* 0 or -_bf._size, for inline putc */
        /* operations */
        void    *_cookie;       /* cookie passed to io functions */
        int     (*_close)(void *);
        int     (*_read) (void *, char *, int);
        fpos_t  (*_seek) (void *, fpos_t, int);
        int     (*_write)(void *, const char *, int);
        /* file extension */
        struct  __sbuf _ext;
        /* separate buffer for long sequences of ungetc() */
        unsigned char *_up;     /* saved _p when _p is doing ungetc data 
*/
        int     _ur;            /* saved _r when _r is counting ungetc 
data */
        /* tricks to meet minimum requirements even when malloc() fails */
        unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
        unsigned char _nbuf[1]; /* guarantee a getc() buffer */
        /* separate buffer for fgetln() when line crosses buffer boundary 
*/
        struct  __sbuf _lb;     /* buffer for fgetln() */
        /* Unix stdio files get aligned to block boundaries on fseek() */
        int     _blksize;       /* stat.st_blksize (may be != _bf._size) 
*/
        fpos_t  _offset;        /* current lseek offset */
} FILE;
------- 8< ------- 8< --------
Molto piu` chiaro. Ho capito, la prossima volta quando ho dubbi
leggo il codice di NetBSD! :-D
Grazie,
Rzl

 cos'è? Insomma, è uno struct?
Lo Standard non prescrive come dev'essere definito il tipo FILE. 
Ogni implementazione avrà la sua definizione. È un dettaglio implementativo
che non è necessario conoscere, giacché l'instanziazione, l'uso e la
distruzione di istanze di FILE avvengono tramite funzioni apposite, e mai
in modo esplicito. Se cerchi negli header troverai la dichiarazione, e
forse (ma non necessariamente) la definizione.
Max

 e forse (ma non necessariamente) la definizione.
Beh, questo ha senso.
La mia non era una critica, è solo che sono abituato a sapere
che tipo di strutture dati sto trattando, sai com'è...
Grazie della risposta cmq :)
-- 
rzl

 di strutture dati sto trattando, sai com'è...
Non serve a molto, a parte per cultura personale. Appena cambi 
l'architettura ti cambiano molte cose sotto i piedi; tanto vale...

Ciao,
cerco di risponderti in modo semplice. In qualche punto ho volutamente
semplificato le cose per non andare troppo in profondita'.
quando compili un programma in C, le entita' coinvolte sono 3:
- ll tuo programma (es: stampa () )
- La libreria standard (es: fopen () ) - non e' in esecuzione, ma
viene linkata al tuo programma
- Il sistema operativo (es: open () ) - in esecuzione
La struttura FILE e' presente nella libreria standard e trovi la sua
definizione nel file <stdio.h>
Tale struttura ha diversi campi.
La struttura FILE e' diversa da compilatore a compilatore: MSVC, GNU,
ARM etc.
La struttura FILE e' utilizzata dalle funzioni fopen( ), fwrite ( ),
etc
Se guardi il sorgente, l'ultima riga della funzione fwrite( ) contiene
la chiama alla funzione:   write( )
La funzione write() e' una chiamata di sistema, cioe' una funzione del
sistema operativo.
La funzione write() ha il compito di scrivere i dati su disco.
La funzione write() scrive sempre un settore, cioe' 512 byte.
Se devi scrivere 1 byte, butti via gli altri 511.
Al ritorno della funzione write() i dati sono in transito sul bus PCI
e stanno andando verso il controller del disco.
Al ritorno della funzione fwrite() non puoi mai essere certo che i
tuoi dati sono su disco.
Se vuoi essere certo che i tuoi dati sono su disco, dopo la fwrite()
devi chiamare la fflush() oppure chiudere il file con la fclose().
ciao,
Enrico

 Enrico