Réponses:
Un descripteur de fichier est un "handle" d'entier de bas niveau utilisé pour identifier un fichier ouvert (ou socket, ou autre) au niveau du noyau, sous Linux et d'autres systèmes de type Unix.
Vous passez des descripteurs de fichiers "nus" aux appels Unix réels, tels que read()
, write()
etc.
Un FILE
pointeur est une construction de niveau bibliothèque standard C, utilisée pour représenter un fichier. L' FILE
encapsule le descripteur de fichier et ajoute une mise en mémoire tampon et d'autres fonctionnalités pour faciliter les E / S.
Vous passez des FILE
pointeurs vers des fonctions C standard telles que fread()
et fwrite()
.
fd
est le premier argument de read()
. Pourquoi appelez-vous cela nu?
FILE *
, le descripteur de fichier entier est "less wrapped", c'est-à-dire "nu".
L'un est tamponné ( FILE *
) et l'autre non. En pratique, vous voulez l'utiliser FILE *
presque toujours lorsque vous lisez à partir d'un 'vrai' fichier (c'est-à-dire sur le lecteur), à moins que vous ne sachiez ce que vous faites ou à moins que votre fichier ne soit en fait une socket ou quelque chose de similaire.
Vous pouvez obtenir le descripteur de fichier à l' FILE *
aide de fileno()
et vous pouvez ouvrir une mémoire tampon à FILE *
partir d'un descripteur de fichier en utilisantfdopen()
Un descripteur de fichier est juste un entier que vous obtenez de l' open()
appel POSIX . En utilisant le standard C, fopen()
vous récupérez une FILE
structure. La FILE
structure contient ce descripteur de fichier entre autres, comme l'indicateur de fin de fichier et d'erreur, la position du flux, etc.
Donc, utiliser fopen()
vous donne une certaine quantité d'abstraction par rapport à open()
. En général, vous devriez l'utiliser fopen()
car c'est plus portable et vous pouvez utiliser toutes les autres fonctions C standard qui utilisent la FILE
structure, ie, fprintf()
et la famille.
Il n'y a aucun problème de performances avec l'un ou l'autre.
Descripteur de fichier vs pointeur de fichier
Descripteur de fichier:
Le descripteur de fichier est une valeur entière renvoyée par open()
un appel système.
int fd = open (filePath, mode);
Pointeur de fichier:
Le pointeur de fichier est un pointeur vers une structure C renvoyée par la fopen()
fonction de bibliothèque, qui est utilisée pour identifier un fichier, encapsuler le descripteur de fichier, la fonctionnalité de mise en mémoire tampon et toutes les autres fonctionnalités nécessaires aux opérations d'E / S. Le pointeur de fichier est de type FILE , dont la définition se trouve dans "/usr/include/stdio.h" . Cette définition peut varier d'un compilateur à l'autre.
FILE *fp = fopen (filePath, mode);
// A FILE Structure returned by fopen
typedef struct
{
unsigned char *_ptr;
int _cnt;
unsigned char *_base;
unsigned char *_bufendp;
short _flag;
short _file;
int __stdioid;
char *__newbase;
#ifdef _THREAD_SAFE
void *_lock;
#else
long _unused[1];
#endif
#ifdef __64BIT__
long _unused1[4];
#endif /* __64BIT__ */
} FILE;
Vous voulez ajouter des points qui pourraient être utiles.
À PROPOS FILE *
Je l'utilise plusieurs fois pour les journaux de débogage. exemple,
FILE *fp;
fp = fopen("debug.txt","a");
fprintf(fp,"I have reached till this point");
fclose(fp);
À PROPOS FILE DESCRIPTOR
Il est généralement utilisé pour IPC.
Donne un contrôle de bas niveau aux fichiers sur les systèmes * nix (périphériques, fichiers, sockets, etc.), donc plus puissant que le FILE *
.
fdopen()
pour faire des choses comme IPC et des appareils avec FILE*
?
FILE*
, mais vous pouvez créer un à FILE*
partir d'un descripteur de fichier ( fdopen()
) et fermer ultérieurement le FILE
fermera également le descripteur. Par conséquent, vous pouvez faire IPC, mais vous devez gérer un peu les descripteurs de fichiers pour faciliter tout IPC direct.
FILE *
est plus utile lorsque vous travaillez avec des fichiers texte et entrée / sortie utilisateur, car il vous permet d'utiliser les fonctions de l' API comme sprintf()
, sscanf()
, fgets()
, feof()
etc.
L'API de descripteur de fichier est de bas niveau, elle permet donc de travailler avec des sockets, des tubes, des fichiers mappés en mémoire (et des fichiers normaux, bien sûr).
Juste un petit mot pour terminer la discussion (si intéressé) ...
fopen
peut être non sécurisé, et vous devriez probablement utiliser fopen_s
ou open
avec un jeu de bits exclusif. C1X offre des x
modes, vous pouvez donc fopen
avec les modes "rx"
, "wx"
etc.
Si vous utilisez open
, vous pourriez envisager open(..., O_EXCL | O_RDONLY,... )
ou open(..., O_CREAT | O_EXCL | O_WRONLY,... )
.
Voir, par exemple, Ne pas faire d'hypothèses sur fopen () et la création de fichiers .
fopen_s
ne semble pas être disponible avec POSIX
, je suppose que la soultion la plus portable serait de open(2)
et ensuite fdopen(2)
. (laissant les fenêtres de côté). De plus, qu'est-ce qui serait plus rapide fopen_s()
ou open(2)
suivi fdopen(2)
?
Les appels système utilisent principalement un descripteur de fichier, par exemple read
et write
. La fonction de bibliothèque utilisera les pointeurs de fichier ( printf
, scanf
). Mais les fonctions de bibliothèque utilisent uniquement des appels système en interne.
J'ai trouvé une bonne ressource ici , donnant un aperçu de haut niveau des différences entre les deux:
Lorsque vous souhaitez effectuer une entrée ou une sortie dans un fichier, vous avez le choix entre deux mécanismes de base pour représenter la connexion entre votre programme et le fichier: les descripteurs de fichier et les flux. Les descripteurs de fichiers sont représentés comme des objets de type int, tandis que les flux sont représentés comme des objets FILE *.
Les descripteurs de fichier fournissent une interface primitive de bas niveau pour les opérations d'entrée et de sortie. Les descripteurs de fichiers et les flux peuvent représenter une connexion à un périphérique (tel qu'un terminal), ou un tube ou une socket pour communiquer avec un autre processus, ainsi qu'un fichier normal. Mais, si vous souhaitez effectuer des opérations de contrôle spécifiques à un type particulier de périphérique, vous devez utiliser un descripteur de fichier; il n'y a aucune possibilité d'utiliser les flux de cette manière. Vous devez également utiliser des descripteurs de fichier si votre programme doit effectuer une entrée ou une sortie dans des modes spéciaux, tels que l'entrée non bloquante (ou interrogée) (voir Indicateurs d'état de fichier).
Les flux fournissent une interface de niveau supérieur, superposée aux fonctionnalités de descripteur de fichier primitif. L'interface de flux traite tous les types de fichiers à peu près de la même manière, la seule exception étant les trois styles de mise en mémoire tampon que vous pouvez choisir (voir Mise en mémoire tampon de flux).
Le principal avantage de l'utilisation de l'interface de flux est que l'ensemble des fonctions permettant d'effectuer des opérations d'entrée et de sortie réelles (par opposition aux opérations de contrôle) sur les flux est beaucoup plus riche et plus puissant que les fonctionnalités correspondantes pour les descripteurs de fichiers. L'interface de descripteur de fichier ne fournit que des fonctions simples pour transférer des blocs de caractères, mais l'interface de flux fournit également de puissantes fonctions d'entrée et de sortie formatées (printf et scanf) ainsi que des fonctions d'entrée et de sortie orientées caractères et lignes.
Étant donné que les flux sont implémentés en termes de descripteurs de fichier, vous pouvez extraire le descripteur de fichier d'un flux et effectuer des opérations de bas niveau directement sur le descripteur de fichier. Vous pouvez également ouvrir initialement une connexion en tant que descripteur de fichier, puis créer un flux associé à ce descripteur de fichier.
En général, vous devriez vous en tenir à l'utilisation de flux plutôt que de descripteurs de fichiers, sauf si vous souhaitez effectuer une opération spécifique qui ne peut être effectuée que sur un descripteur de fichier. Si vous êtes un programmeur débutant et que vous n'êtes pas sûr des fonctions à utiliser, nous vous suggérons de vous concentrer sur les fonctions d'entrée formatées (voir Entrée formatée) et les fonctions de sortie formatées (voir Sortie formatée).
Si vous êtes préoccupé par la portabilité de vos programmes vers des systèmes autres que GNU, vous devez également savoir que les descripteurs de fichiers ne sont pas aussi portables que les flux. Vous pouvez vous attendre à ce que tout système exécutant ISO C prenne en charge les flux, mais les systèmes non GNU peuvent ne pas du tout prendre en charge les descripteurs de fichiers, ou peuvent implémenter uniquement un sous-ensemble des fonctions GNU qui fonctionnent sur des descripteurs de fichiers. Cependant, la plupart des fonctions de descripteur de fichier de la bibliothèque GNU C sont incluses dans le standard POSIX.1.