Y a-t-il une raison (autre que syntaxique) que vous voudriez utiliser
FILE *fdopen(int fd, const char *mode);
ou
FILE *fopen(const char *path, const char *mode);
au lieu de
int open(const char *pathname, int flags, mode_t mode);
lors de l'utilisation de C dans un environnement Linux?
Premièrement, il n'y a pas de bonne raison d'utiliser fdopen
si fopen
est une option et open
est l'autre choix possible. Vous n'auriez pas dû utiliser open
pour ouvrir le fichier si vous voulez un _FILE *
_. Donc, inclure fdopen
dans cette liste est incorrect et déroutant car il ne ressemble pas beaucoup aux autres. Je vais maintenant passer à l’ignorer, car la distinction importante est ici entre un C standard _FILE *
_ et un descripteur de fichier spécifique au système d’exploitation.
Il existe quatre raisons principales d'utiliser fopen
au lieu de open
.
fopen
vous fournit un tampon IO qui peut s'avérer beaucoup plus rapide que ce que vous faites avec open
.fopen
effectue la traduction de fin de ligne si le fichier n'est pas ouvert en mode binaire, ce qui peut s'avérer très utile si votre programme est jamais porté dans un environnement non Unix.FILE *
_ vous donne la possibilité d'utiliser fscanf
et d'autres fonctions stdio.open
.À mon avis, la fin de ligne se trouve plus souvent dans votre chemin qu’elle ne vous aide, et l’analyse de fscanf
est si faible que vous finissez inévitablement par la lancer en faveur de quelque chose de plus utile.
Et la plupart des plates-formes prenant en charge C ont une fonction open
.
Cela laisse la question tampon. Dans les endroits où vous lisez ou écrivez principalement un fichier de manière séquentielle, la prise en charge de la mise en mémoire tampon est vraiment utile et représente une grande amélioration de la vitesse. Mais cela peut entraîner des problèmes intéressants, dans lesquels les données ne se retrouvent pas dans le fichier alors que vous vous attendez à ce qu'elles soient là. Vous devez vous rappeler de fclose
ou fflush
aux moments appropriés.
Si vous effectuez des recherches (alias fsetpos
ou fseek
dont la seconde est légèrement plus délicate à utiliser de manière conforme aux normes), l'utilité de la mise en mémoire tampon diminue rapidement.
Bien sûr, mon parti pris est que j’ai tendance à travailler beaucoup avec des sockets, et le fait que vous vouliez vraiment faire du non-blocage IO (que _FILE *
_ échoue totalement à supporter de manière raisonnable) sans aucun tampon et souvent avec des exigences d’analyses complexes colorent vraiment mes perceptions.
open()
est un appel OS de bas niveau. fdopen()
convertit un descripteur de fichier de niveau os en abstraction FILE de niveau supérieur du langage C. fopen()
appelle open()
en arrière-plan et vous attribue directement un pointeur FILE.
L’utilisation d’objets FILE plutôt que de descripteurs de fichiers bruts présente plusieurs avantages, ce qui inclut une plus grande facilité d’utilisation mais également d’autres avantages techniques, tels que la mise en mémoire tampon intégrée. En particulier, la mise en mémoire tampon procure généralement un avantage considérable en termes de performances.
fopen vs ouvert en C
1) fopen
est un fonction de bibliothèque alors que open
est un appel système.
2) fopen
fournit IO en mémoire tampon, ce qui est plus rapide comparé à open
qui est sans mémoire tampon.
3) fopen
est portable alors que open
pas portable (ouvert est spécifique à l'environnement).
4) fopen
renvoie un pointeur sur une structure FILE (FILE *); open
renvoie un entier identifiant le fichier.
5) Un FILE *
vous donne la possibilité d'utiliser fscanf et d'autres fonctions stdio.
Si vous avez un FILE *
, vous pouvez utiliser des fonctions telles que fscanf
, fprintf
et fgets
etc. Si vous avez juste le descripteur de fichier, vous avez limité (mais probablement plus rapide) routines d'entrée et de sortie read
, write
etc.
À moins que vous ne fassiez partie des 0,1% d'applications où open
présente des avantages réels en termes de performances, il n'y a vraiment aucune bonne raison de ne pas utiliser fopen
. En ce qui concerne fdopen
, si vous ne jouez pas avec les descripteurs de fichier, vous n'avez pas besoin de cet appel.
Tenez-vous-en à fopen
et à sa famille de méthodes (fwrite
, fread
, fprintf
, etc.) et vous serez très satisfait. De manière tout aussi importante, les autres programmeurs seront satisfaits de votre code.
Utiliser open, read, write signifie que vous devez vous soucier des interaptions des signaux.
Si l'appel a été interrompu par un gestionnaire de signal, les fonctions renverront -1 et définiront errno sur EINTR.
Donc, la bonne façon de fermer un fichier serait
while (retval = close(fd), retval == -1 && ernno == EINTR) ;
open () sera appelé à la fin de chacune des fonctions de la famille fopen (). open () est un appel système et fopen () sont fournis par les bibliothèques en tant que fonctions d'encapsulation faciles à utiliser pour l'utilisateur
open()
est un appel système spécifique aux systèmes Unix. Il renvoie un descripteur de fichier. Vous pouvez écrire dans un descripteur de fichier en utilisant write()
, qui est un autre appel système.fopen()
est un appel de fonction ANSI C qui renvoie un pointeur de fichier et qui est portable pour les autres systèmes d'exploitation. Nous pouvons écrire dans un pointeur de fichier en utilisant fprintf
.
Sous Unix:
Vous pouvez obtenir un pointeur de fichier à partir du descripteur de fichier en utilisant:
fP = fdopen(fD, "a");
Vous pouvez obtenir un descripteur de fichier à partir du pointeur de fichier en utilisant:
fD = fileno (fP);
Dépend également de ce que les drapeaux doivent être ouverts. En ce qui concerne l'utilisation pour l'écriture et la lecture (et la portabilité), f * doit être utilisé, comme indiqué ci-dessus.
Toutefois, si vous souhaitez spécifier plus que des indicateurs standard (comme les indicateurs rw et append), vous devez utiliser une API spécifique à la plate-forme (telle que POSIX open) ou une bibliothèque qui résume ces informations. La norme C n'a pas de tels drapeaux.
Par exemple, vous voudrez peut-être ouvrir un fichier, s'il existe déjà. Si vous ne spécifiez pas l'indicateur de création, le fichier doit exister. Si vous ajoutez exclusif à créer, le fichier ne sera créé que s'il n'existe pas. Il y en a beaucoup plus.
Par exemple, sur les systèmes Linux, il existe une interface LED exposée via sysfs. Il expose la luminosité de la led à travers un fichier. Écrire ou lire un nombre sous forme de chaîne allant de 0 à 255. Bien sûr, vous ne voulez pas créer ce fichier et y écrire uniquement s’il existe. La bonne chose maintenant: utilisez fdopen pour lire/écrire ce fichier en utilisant les appels standard.
J'ai remplacé open () par fopen () pour mon application, car fopen provoquait des lectures doubles à chaque fois que j'exécutais fopen fgetc. Les doubles lectures ont perturbé ce que j'essayais d'accomplir. open () semble juste faire ce que vous lui demandez.